如何运行多个Haskell IO操作并存储结果?

时间:2018-03-30 17:08:29

标签: haskell

我是Haskell的初学者,所以提前抱歉新手问题。我对monad只有非常肤浅的理解。

我使用模块Persistent中的函数insert。 (我一直关注the tutorial here。)它在数据库中插入一些东西,然后返回ID。我可以这样使用它:

resultId <- insert myItem

对于单个项目可以正常工作。我可以像这样打印出resultId:

liftIO $ print resultId

但是如果我的myItem实际上是一个任意长度的列表呢?我想将insert映射到此列表上,我可以这样做:

resultIds <- mapM_ insert myItemList

但是如果我尝试打印出值:

liftIO $ print resultIds

我得到()。我究竟做错了什么?

1 个答案:

答案 0 :(得分:4)

你非常接近:你需要mapM :: Monad m => (a -> m b) -> t a -> m (t b)而不是mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()

就像已经建议的名称和签名一样,这两个函数都采用monadic函数和a s的遍历(我们现在假设这是一个列表),它将monadic函数应用于所有元素并返回包含结果的可遍历(列表)的monadic函数。

所以如果你写:

    resultIds <- mapM insert myItemList

mapMmapM_之间的区别在于mapM_(如签名已经暗示的那样),您对结果不感兴趣,因此不会计算。原因可能是列表很长(并且生成 by-need ),因此标识符列表永远不会适合内存。

然后resultIds将包含标识符列表。

关于mapM(和mapM_)函数的解释有点过于简单化了,但我认为通常最好先对monad更加舒服,而不是完全了解monadic函数的细节。右。