从精心编写的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))
请解释输出的最后一行[(), ()]
:
*Main> runListT test
([1,2],'a')
([1,2],'b')
[(),()]
答案 0 :(得分:2)
TL; DR:如果您在GHCi中看到了一些您没想到的东西,请考虑产生该结果的行的类型。
test
的类型为ListT IO ()
。如果我们在runListT
上使用ListT m a
,我们最终会得到m [a]
:
runListT :: Monad m => ListT m a -> m [a]
test :: ListT IO ()
runListT test :: IO [()]
由于可以显示[()]
(并且不是()
),GHCi会显示结果。如果绑定它,你将看不到它:
*Main> res <- runListT test
([1,2],'a')
([1,2],'b')
*Main> res
[(),()]
最后,它与replicateM 10 $ print 1
的输出有些相关。它收集print 1
的所有结果,这些结果不是很有趣。但是,编写runListT_
以删除它们很容易:
*Main> let runListT_ m = runListT m >> return ()
*Main> runListT_ test
([1,2],'a')
([1,2],'b')