繁体   English   中英

Haskell:在单个值上运行IO操作列表

[英]Haskell: Running a list of IO operations over a single value

如果我有许多函数是string -> IO () ,是否有一种整洁的方式将它们全部应用于一个单独的值。

op1, op2, op3 :: String -> IO ()

main :: IO ()
main = do
  let str = "test"
  op1 str
  op2 str
  op3 str

不必每次写出str?

只需使用功能应用程序( $ )的地图和部分应用程序:

mapM ($ str) [op1,op2,op3]

不想要结果? 精细。

mapM_ ($ str) [op1,op2,op3]

或者使用Data.Foldable

for_ [op1,op2,op3] ($ str)

编辑:

扩展了for_替代forM_

关于mapM / mapM_ 这些是历史的工件 - 这些操作专门针对Monads,并且可以被删除。 适用的替代方案是traversetraverse_

我建议使用for_traverse_方法,但请注意这些Monoid实例存在:

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

所以在这种特殊情况下,这有效:

  mconcat [op1, op2, op3] str

我会做

op1, op2, op3 :: String -> IO ()

main :: IO ()
main = do
    let str = "test"
    mconcat (sequence [op1, op2, op3] str)

这有点复杂:这里的sequence专门用于输入

[String -> IO ()] -> String -> [IO ()]

mconcat只需要一个IO动作列表(类型[IO ()] )并返回单个IO动作(类型IO () )。

另一个解决方案,这个使用来自Control.Applicative ZipList

let ZipList ios = ZipList [op1,op2,op3] <*> ZipList (repeat str) 
 in sequence ios

暂无
暂无

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

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