Sebastian Fisher wrote:
The nested monadic tails of your lists seem more similar to the nested monadic data described in the ICFP'09 paper with Oleg Kiselyov and Chung-chieh Shan [1]. The ideas described in that paper are on Hackage and your ListT seems similar to the List type in Data.Monadic.List [2] although our version not only uses monadic tails but also monadic heads. See [3] for a tutorial.
A small correction: the tail of ListT is not monadic, but "unpacking" it (getting either a Nil or a Cons) is.
If just the tail was monadic one couldn't create a list which might be empty depending on a monadic result,
For example:
linesFromUser :: ListT IO String
linesFromUser = takeWhile (not . null) . joinM $ repeat getLine
linesFromUser is a list of lines from the user until an empty line, not including the empty line.
the first line entered by the user determines if the list is empty or not.