为GHCI重新装箱纯值的目的

Ber*_*ian 0 haskell io-monad

有人可以向我解释为什么在使用时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)

我不明白我的逻辑存在缺陷:

  1. 使用listAction给了我一个IO [FilePath]
  2. 我拆箱的价值listAction[FilePath],我给它length
  3. 现在不应该length只是将结果打印到控制台是纯函数吗?如果我说的话,是不是一样的length [1,2,3]

为什么我要再次装箱?不是monad类型的结果:[FilePath]如果是这样,为什么它不能打印结果?

lenAction=list>>=return . length
Run Code Online (Sandbox Code Playgroud)

mel*_*ene 5

这只是一个类型错误.

>>=(与之一起使用时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 listActionlength <$> listAction.)