如何在 Haskell 中创建未评估的映射?

How can I create a non-evaluated mapping in Haskell?

我有这个功能

let tid = forkIO $ sequence_ ioOps
let ioOps = take 200 $ cycle $ intersperse (threadDelay (1000000*60*20)) $ mapM putStrLn stoJeLuka

我知道它不漂亮,但我只是偷偷摸摸。

我正在尝试 运行 一个脚本,该脚本在特定时期输出 stoJeLuka :: [String] 中提供的字符串之一。

我的问题是我的 mapM 在我想要它之前评估了 putStrLn。 我如何只创建一个 list :: [IO a] 而不评估这些 putStrLn

你的问题有点不清楚,因为你还没有真正解释你想让代码做什么。但有些东西看起来很可疑。具体来说,mapM putStrLn stoJeLuka 是一个 IO 动作, 产生 一个列表;它实际上不是一个列表。所以调用 intersperse 会产生类型错误。您可能打算使用 mapfmap 而不是 mapM。我猜您的代码可能实际上已经这样做了,并且您在抱怨这些事情何时相对于您未显示的其他代码执行。

mapM 几乎是 sequence . map,这意味着它 被评估并变成一个动作。

您想简单地 map putStrLn - 这将创建一个 [IO ()] 类型的列表,而不执行所需的操作。当您想要打印它时,只需 sequence 该列表,或对其调用 foldl (>>) (return ()),就像在 mapM_.

中一样