5

你能创建一个函数列表,然后按顺序执行它们,也许将它们传递给 do 表示法吗?

我目前正在通过映射数据列表来做到这一点,并且想知道我是否可以调用以某种方式将结果作为一系列顺序调用传递?

4

3 回答 3

9

像这样的东西?

sequence [putStrLn "Hello", putStrLn "World"]
于 2010-03-10T19:05:51.840 回答
5

如果这些是函数,即纯函数,那么您可以使用($)或“应用”:

execute functions argument = map ($argument) functions
-- execute [id,(1+),(1-)] 12 => [12,13,-11]

当然,不能保证这会按顺序发生,但您会得到一个返回值列表。

如果这些是动作,即不纯,那么你想要的就是sequence_

sequence_ [putStr "Hello", putStr " world", putStrLn "!"]

sequence_自己写很容易:

sequence_ [] = return ()
sequence_ (action:actions) = action >> sequence_ actions

还有一个sequence(不带下划线)运行一堆动作并返回它们的结果:

main = do
  ss <- sequence [readFile "foo.txt", readFile "bar.txt", readFile "baz.txt"]
  -- or ss <- mapM readFile ["foo.txt", "bar.txt", "baz.txt"]
于 2010-03-10T19:13:43.810 回答
3

到目前为止的答案很好,但如果您还希望每个函数不作用于原始数据而是作用于前一个函数的结果,请查看折叠函数,例如 foldl、foldl1 和 foldr:

fns = [(1-), (+2), (abs), (+1)]
helperFunction a f = f a
test1 n = foldl helperFunction n fns

你可能需要单子版本 foldM 和 foldM_ :

import Control.Monad
import Data.Char

helperFunction a f = f a
prnt = \s-> do putStrLn s; return s
actions = [return, prnt, return.reverse, prnt, return.(map toUpper), prnt, return.reverse, prnt] 
test2 str = foldM_ helperFunction str actions 
于 2010-03-11T05:44:41.330 回答