Reputation: 41909
Given the following from the well-written From Simple IO to Monad Transformers:
import Control.Monad.List
type Lio = ListT IO
test :: Lio ()
test = do
x <- return [1,2]
y <- ListT $ return ['a', 'b']
lift $ putStrLn (show (x, y))
Please explain the final line of output, [(), ()]
:
*Main> runListT test
([1,2],'a')
([1,2],'b')
[(),()]
Upvotes: 1
Views: 144
Reputation: 105876
TL;DR: If you see something you didn't expect in GHCi, think of the type of the line that yielded that result.
test
has the type ListT IO ()
. If we use runListT
on a ListT m a
, we end up with a m [a]
:
runListT :: Monad m => ListT m a -> m [a]
test :: ListT IO ()
runListT test :: IO [()]
Since [()]
can be shown (and is not ()
), GHCi shows you the result. You won't see it if you bind it:
*Main> res <- runListT test
([1,2],'a')
([1,2],'b')
*Main> res
[(),()]
In the end, it's somewhat related to the output of replicateM 10 $ print 1
. It collects all the results of print 1
, which aren't very interesting. However, it's easy to write runListT_
to get rid of those:
*Main> let runListT_ m = runListT m >> return ()
*Main> runListT_ test
([1,2],'a')
([1,2],'b')
Upvotes: 3