你能把Haskell列表变成一系列的指令吗?

时间:2010-03-10 19:02:46

标签: list haskell do-notation

您可以创建一个函数列表,然后按顺序执行它们,也许可以将它们传递给do notation吗?

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

3 个答案:

答案 0 :(得分:9)

这样的东西?

sequence [putStrLn "Hello", putStrLn "World"]

答案 1 :(得分:5)

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

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"]

答案 2 :(得分:3)

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

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

你可能需要monadic版本,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