有人可以向我解释为什么在使用时ghci我必须"重新装箱"monad返回的值吗?
listAction=listDirectory "D:\\"
lenAction=listAction>>=length
Run Code Online (Sandbox Code Playgroud)
错误:
Couldn't match type `Int' with `IO b0'
Expected type: [FilePath] -> IO b0
Actual type: [FilePath] -> Int
Run Code Online (Sandbox Code Playgroud)
我不明白我的逻辑存在缺陷:
listAction给了我一个IO [FilePath]listAction来[FilePath],我给它lengthlength只是将结果打印到控制台是纯函数吗?如果我说的话,是不是一样的length [1,2,3]?为什么我要再次装箱?不是monad类型的结果:[FilePath]如果是这样,为什么它不能打印结果?
lenAction=list>>=return . length
Run Code Online (Sandbox Code Playgroud)
这只是一个类型错误.
>>=(与之一起使用时IO)的类型是
(>>=) :: IO a -> (a -> IO b) -> IO b
Run Code Online (Sandbox Code Playgroud)
也就是说,第二个参数必须是一个返回type值的函数IO something.length没有这种类型,所以类型检查器抱怨.
如您所示,return :: a -> IO a可用于将值提升到IO.这是解决问题的一种方法.
另一种方法是使用fmap:
fmap length listAction
Run Code Online (Sandbox Code Playgroud)
这是因为fmap(当与之一起使用时IO)
fmap :: (a -> b) -> IO a -> IO b
Run Code Online (Sandbox Code Playgroud)
(做同样事情的其他方式包括liftM length listAction和length <$> listAction.)