0

有人可以向我解释为什么在使用时ghci我必须“重新装箱”单子返回的值吗?

 listAction=listDirectory "D:\\"
 lenAction=listAction>>=length 

错误:

Couldn't match type `Int' with `IO b0'
      Expected type: [FilePath] -> IO b0
        Actual type: [FilePath] -> Int

我不明白我的逻辑在哪里有缺陷:

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

为什么我必须再次装箱?不是类型单子的结果:[FilePath]如果是,为什么它不能打印结果?

lenAction=list>>=return . length
4

1 回答 1

5

这只是一个类型错误。

>>=(与 一起使用时IO)的类型是

(>>=) :: IO a -> (a -> IO b) -> IO b

也就是说,第二个参数必须是返回类型值的函数IO somethinglength没有这样的类型,所以类型检查器会抱怨。

如您所见,return :: a -> IO a可用于将值提升到IO. 这是解决问题的一种方法。

另一种方法是使用fmap

fmap length listAction

这是有效的,因为fmap(当与 一起使用时IO)是

fmap :: (a -> b) -> IO a -> IO b

(做同样事情的其他方法包括liftM length listActionlength <$> listAction。)

于 2018-08-13T16:28:40.473 回答