考虑以下Haskell程序。我想计划在“流型”功能操作流(这里只是列出了实现)。诸如normalStreamFunc延迟列表的伟大的工作。我可以通过无限列表normalStreamFunc并有效地摆脱另一个无限,但与一个函数映射到每个值。诸如effectfulStreamFunc不工作。IO操作意味着之前我需要评估整个列表可以实现个人价值。例如,程序的输出是:
a
b
c
d
"["a","b"]"
但是我想要的是一种编写effectfulStreamFunc这样程序产生:
a
b
"["a","b"]"
让剩下的未鉴定的行动。使用unsafePerformIO我可以想象一个解决方案,但让年代说我的表。这是计划:
import IO
normalStreamFunc :: [String] -> [String]
normalStreamFunc (x:xs) = reverse(x) : normalStreamFunc xs
effectfulStreamFunc :: [String] -> IO [String]
effectfulStreamFunc [] = return []
effectfulStreamFunc (x:xs) = do
putStrLn x
rest <- effectfulStreamFunc xs
return (reverse(x):rest)
main :: IO ()
main = do
let fns = ["a", "b", "c", "d"]
es <- effectfulStreamFunc fns
print $ show $ take 2 es
<强>更新:< /强>
谢谢你们所有人的帮助和周到的反馈。我没有见过<代码> < /代码>操作符序列,这是有用的了解。我想到一个比较优雅的方式传送IO(字符串)值,而不是字符串,但作用有限的编程风格,因为我想其他流函数作用于字符串本身,而不是行为可以产生一个字符串。但是,基于思考其他的反应,我想我明白为什么这是无法解决的。在简单的情况下,我提出,我真正想要的是<代码> < /代码>操作符序列,因为我认为流排序隐含一个排序的操作。事实上,没有这样的顺序必然隐含。这变得更加清晰,我当我想到流函数需要两个流作为输入(例如成对除了两个流)。如果两个IO流执行“输入”,这些IO操作的顺序是未定义的(当然,除非我们自己定义通过测序IO单子)。问题解决了,谢谢大家!