简体   繁体   English

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

[英]How can I run multiple Haskell IO actions and store the results?

I'm a Haskell beginner, so sorry in advance for the newbie question. 我是Haskell的初学者,所以对于新手问题,请提前表示抱歉。 I only have a very superficial understanding of monads. 我对单子只有一个非常肤浅的理解。

I'm using the function insert from the module Persistent. 我正在使用Persistent模块中的功能insert (I've been following the tutorial here .) It inserts something in a database, and returns the ID. (我在这里一直在关注本教程 。)它在数据库中插入一些内容,并返回ID。 I can use it like this: 我可以这样使用它:

resultId <- insert myItem

That works fine for a single item. 对于单个项目来说效果很好。 I can print out the resultId like this: 我可以这样打印出resultId:

liftIO $ print resultId

But what if my myItem is actually a list of arbitrary length? 但是,如果myItem实际上是任意长度的列表怎么办? I want to map insert over this list, which I can seem to do with: 我想在此列表上映射insert ,这似乎可以做到:

resultIds <- mapM_ insert myItemList

but then if I try to print out the values: 但是如果我尝试打印出这些值:

liftIO $ print resultIds

I just get () . 我刚得到() What am I doing wrong? 我究竟做错了什么?

You are quite close: you need mapM :: Monad m => (a -> mb) -> ta -> m (tb) instead of mapM_ :: (Foldable t, Monad m) => (a -> mb) -> ta -> m () 您非常接近:您需要mapM :: Monad m => (a -> mb) -> ta -> m (tb) mapM_ :: (Foldable t, Monad m) => (a -> mb) -> ta -> m () mapM :: Monad m => (a -> mb) -> ta -> m (tb)代替mapM_ :: (Foldable t, Monad m) => (a -> mb) -> ta -> m ()

Like the name and the signature already suggest, both functions take a monadic function and a traversable (let us for now assume that that is a list) of a s, and it applies the monadic function to all elements and returns a monadic function that contains a traversable (list) of the results. 就像已经暗示的名称和签名一样,这两个函数都带有一个monadic函数和a s的可遍历(现在让我们假定它是一个列表),并将monadic函数应用于所有元素并返回包含以下内容的monadic函数:结果的可遍历(列表)。

So if you write: 因此,如果您写:

    resultIds <- mapM insert myItemList

The difference between mapM and mapM_ is that in the case of mapM_ (like the signature already suggests), you are not interested in the outcome, and thus it is not calculated. 之间的区别mapMmapM_是在的情况下mapM_ (如签名已经建议),你是不感兴趣的结果,因此不计算。 A reason for this could possibly be that the list is very long (and generated by-need ), and thus the list of identifiers would never fit in memory. 造成这种情况的原因可能是列表很长(并且是按需生成 ),因此标识符列表将永远无法容纳在内存中。

then resultIds will contain a list of identifiers. 然后resultIds将包含一个标识符列表。

The explanation about the mapM (and mapM_ ) function is a bit an oversimplification, but I think that it is usually better to first get more comfortable about monads, than getting details about monadic functions completely right. 关于mapM (和mapM_ )函数的解释有些过分简化,但我认为通常最好是先对monad感到更自在,而不是完全正确地了解monadic函数的细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM