简体   繁体   English

在哈斯克尔的Monads上循环

[英]Looping over Monads in Haskell

I am really new to Haskell, so this might be a stupid question. 我对Haskell很新,所以这可能是一个愚蠢的问题。 I have a function 我有一个功能

foo :: Int -> IO ()

whose result will print some useful information. 其结果将打印一些有用的信息。 Now I want to do this: 现在我想这样做:

do
    foo 0
    foo 1
    foo 0
    foo 2
    foo 3

How can I write this as a loop? 我怎么能把它写成循环? My problem is to 'concatenate' the Monads, which is done automatically by the do statement... 我的问题是'连接'Monads,这是由do语句自动完成的......

Thank you for your help! 谢谢您的帮助!

mapM_ foo [0,1,0,2,3] will do the trick. mapM_ foo [0,1,0,2,3]将成功。

What's perhaps more important is "how does one figure that out?" 或许更重要的是“人们怎么想出来的?” Hoogle is a wonderful tool. Hoogle是一个很棒的工具。 You want to apply a function with signature Int -> IO () to a bunch of Int s to get a new IO action. 您希望将具有签名Int -> IO ()的函数应用于一堆Int以获取新的IO操作。 The thing you're looking for will thus have signature (Int -> IO ()) -> [Int] -> IO () , so we go and ask Hoogle for functions with that signature . 因此,您正在寻找的东西将具有签名(Int -> IO ()) -> [Int] -> IO () ,因此我们向Hoogle请求具有该签名的函数 The second result is mapM_ , whose signature is 第二个结果是mapM_ ,其签名是

Monad m => (a -> m b) -> [a] -> m ()

Right, so mapM_ in fact works with any monad (not just IO ) and any type (not just Int ). 是的,所以mapM_实际上适用于任何 monad(不仅仅是IO )和任何类型(不仅仅是Int )。 When you think about it, that's not surprising at all. 当你想到它时,这一点都不奇怪。

You want the mapM_ combinator, which maps a function returning a monadic value over a list, and uses the bind operator to sequence the results: 你想要mapM_ combinator,它映射一个函数,在一个列表上返回一个monadic值,并使用bind运算符对结果进行排序:

>> let foo n = putStrLn (show n ++ "!")
>> mapM_ foo [0,1,0,2,3]
0!
1!
0!
2!
3!

Sometimes people like to use the flipped version 有时人们喜欢使用翻转版本

for :: Monad m => [a] -> (a -> m b) -> m ()
for = flip mapM_

which looks more like imperative code: 看起来更像命令式代码:

>> for [1..5] $ \n ->
     putStrLn ("Number: " ++ show n)
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

Note that a combinator called forM_ is defined in Control.Monad and does exactly the same thing as the combinator I've called for . 需要注意的是一个叫做组合子forM_在定义Control.Monad和不完全一样的东西的组合子我已经叫for

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

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