简体   繁体   English

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

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

if I have a number of functions that are string -> IO () , is there a tidy way to apply them all to a single value in sequence. 如果我有许多函数是string -> IO () ,是否有一种整洁的方式将它们全部应用于一个单独的值。

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

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

with out having to write out str each time? 不必每次写出str?

Just use a map and partial application of function application ( $ ): 只需使用功能应用程序( $ )的地图和部分应用程序:

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

Don't want the result? 不想要结果? Fine. 精细。

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

Or use Data.Foldable : 或者使用Data.Foldable

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

EDIT: 编辑:

Expanding on the commentary of for_ being a replacement for forM_ . 扩展了for_替代forM_

The same can be said about mapM / mapM_ . 关于mapM / mapM_ These are artifacts of history - the operations are specialized to Monads and could, argueably should, be deleted. 这些是历史的工件 - 这些操作专门针对Monads,并且可以被删除。 The Applicative alternative is traverse and traverse_ . 适用的替代方案是traversetraverse_

I'd recommend the for_ or traverse_ approach, but note that these Monoid instances exist: 我建议使用for_traverse_方法,但请注意这些Monoid实例存在:

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

So in this particular case, this works: 所以在这种特殊情况下,这有效:

  mconcat [op1, op2, op3] str

I would do 我会做

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

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

This is somewhat complicated: sequence here is specialized to type 这有点复杂:这里的sequence专门用于输入

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

while mconcat simply takes a list of IO actions (type [IO ()] ) and returns a single IO action (type IO () ). mconcat只需要一个IO动作列表(类型[IO ()] )并返回单个IO动作(类型IO () )。

Another solution, this one using ZipList from Control.Applicative : 另一个解决方案,这个使用来自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