在同一输入上调用多个IO功能

时间:2015-11-11 12:43:06

标签: haskell io applicative

假设我有一个元组列表(例如[(a,b)]),每个元组都是先前计算的结果。

我希望在每个元素上应用几个函数(例如,一个函数可能会打印另一个函数,通过网络等发送它。)

我尝试了什么:

import Control.Applicative
main = do
          let a = [1..5]
          let fs = [(\k-> putStrLn $ show $ k*2), (\k-> putStrLn $ show $ k-2), (\k-> putStrLn $ show $ k*10)]
          let res = fs <*> a 
          putStrLn $ "Yo"

只打印"Yo"

3 个答案:

答案 0 :(得分:4)

如果仔细观察,res的类型为[IO ()],您就永远不会使用它。

所以只需sequence

main = do
  let a = [1..5]
  let fs = [(\k-> putStrLn $ show $ k*2), (\k-> putStrLn $ show $ k-2), (\k-> putStrLn $ show $ k*10)]
  let res = fs <*> a
  sequence res
  putStrLn $ "Yo"

如果您想知道如何使整个块更简洁,而不是重构映射列表(使用 sections ),请使用print(这基本上就是您的putStrLn . show)和mapM_

main = do
  mapM_ print $ [(* 2), (+ (-2)), (* 10)] <*> [1..5]
  putStrLn $ "Yo"

将给出

λ> :main
2
4
6
8
10
-1
0
1
2
3
10
20
30
40
50
Yo

也是;)

请注意,您可能不应该将所有IO内容与纯计算混合在一起 - 而是重构整数列表:

myCombinations :: [Int] -> [Int]
myCombinations ns = [(* 2), (+ (-2)), (* 10)] <*> ns

main = do
  mapM_ print $ myCombinations [1..5]
  putStrLn $ "Yo"

(当然,随着你的进展引入功能,但我无法猜测你在这里想要实现的目标)

从中你可以检查你的纯函数/值:

λ> myCombinations [1..5]
[2,4,6,8,10,-1,0,1,2,3,10,20,30,40,50]

并且可能获得很多可读性;)

答案 1 :(得分:0)

如果您有ios :: [a -> IO b]列表,则可以使用mapM ($ aValue) ios获取IO [b]mapM_获取IO ()

答案 2 :(得分:0)

let不会将任何内容绑定到monad中。因此IO并不关心您使用<*>对列表中的函数进行操作,只要您不以任何方式在monad操作中使用结果。

要简单地执行......井,序列中的操作列表,您可以使用sequence

    let res = fs <*> a
    sequence res