如何在 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
会产生类型错误。您可能打算使用 map
或 fmap
而不是 mapM
。我猜您的代码可能实际上已经这样做了,并且您在抱怨这些事情何时相对于您未显示的其他代码执行。
mapM
几乎是 sequence . map
,这意味着它 将 被评估并变成一个动作。
您想简单地 map putStrLn
- 这将创建一个 [IO ()]
类型的列表,而不执行所需的操作。当您想要打印它时,只需 sequence
该列表,或对其调用 foldl (>>) (return ())
,就像在 mapM_
.
中一样
我有这个功能
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
会产生类型错误。您可能打算使用 map
或 fmap
而不是 mapM
。我猜您的代码可能实际上已经这样做了,并且您在抱怨这些事情何时相对于您未显示的其他代码执行。
mapM
几乎是 sequence . map
,这意味着它 将 被评估并变成一个动作。
您想简单地 map putStrLn
- 这将创建一个 [IO ()]
类型的列表,而不执行所需的操作。当您想要打印它时,只需 sequence
该列表,或对其调用 foldl (>>) (return ())
,就像在 mapM_
.