(not exactly an answer to the question, but related)
I like to represent trees of a as "ListT [] a
". (ListT
from the List
package in hackage)
Then the answer for this question is just to use the function lastL
.
"Monad m => ListT m a
" is a monadic list containing "a
"s, where trying to get the next list item (which may find out there is no such item) is a monadic action in "m
".
A usage example for ListT
- a program that reads numbers from the user until the user does not type a number and prints the sum of numbers after each input:
main =
execute . joinM . fmap print .
scanl (+) 0 .
fmap (fst . head) .
takeWhile (not . null) .
fmap reads .
joinM $ (repeat getLine :: ListT IO (IO String))
Where repeat
, scanl
and takeWhile
are from Data.List.Class
. They work both for regular lists and monadic lists.
joinM :: List l => l (ItemM l a) -> l a -- (l = ListT IO, ItemM l = IO)
execute :: List l => l a -> ItemM l () -- consume the whole list and run its actions
If you are familiar with Python, python iterators/generators are "ListT IO
"s.
When using []
instead of IO
as the monad of the monadic list, the result is a tree. Why? Imagine a list where getting the next item is an action in the list monad - the list monad means there are several options, therefore there are several "next items", which makes it a tree.
You can construct monadic lists either with higher-order functions (like the example above), or with cons
, or with a python-generator notation (with yield
) using the GeneratorT
monad transformer from the generator
package in hackage.
Disclaimer: ListT
and GeneratorT
are in no way widely used. I wrote those and I am not aware of any other users except for myself. There are several of users of equivalent ListT
s, such as the one from the Haskell wiki, NondetT
, and others.