Haskell - 在 Prelude.sequence 函数的结果之间插入线程处理

Haskell - Inserting a thread dealy between the results of Prelude.sequence function

我有一些代码看起来像这样

  listOfIOByteStrings = simpleHttp <$> apiLinks :: [IO ByteString]

其中 apiLinks 是调用某些 API 函数的链接列表。

我也有这个功能

  z = sequence listOfIOByteStrings

sequence 有这种类型 sequence :: Monad m => t (m a) -> m (t a)

我想做的是在每个 ByteString 的评估之间添加一个线程延迟。

我正在考虑使用 threadDelay threadDelay :: Int -> IO ()

这就是我最终要做的事情

listOfContent <- z
pPrint $ filteredTitles . onlyElems . parseXML <$> listOfContent

哪里

parseXML :: ByteString -> [Content]

onlyElems :: [Content] -> [Element]

filteredTitles :: [Element] -> [String]

在序列结果之间应用线程延迟就像这样

printing (filteredTitles . onlyElems . parseXML (bytestring of link1))... 
delay of 1 sec...
printing (filteredTitles . onlyElems . parseXML (bytestring of link2))... 
delay of 1 sec...
printing (filteredTitles . onlyElems . parseXML (bytestring of link3))... 
delay of 1 sec...

我不确定我应该怎么做。

我不太了解您管道中的所有类型,因此请将其视为可以充实的粗略草图。首先,您不想过早调用 sequence。暂时保留 IO Bytestring 值列表。

接下来,您需要一些函数(根据 filteredTitles . onlyElems . parseXML 定义)需要一个 单个 Bytestring 和 returns 一个 IO ()。如果 pPrint 是写类型,这可能只是

process :: IO ByteString -> IO ()
process ibs = do
    bs <- ibs
    pPrint (filteredTitles . onlyElems . parseXML $ bs)

map process (apiLinks >>= simpleHttp) 应生成 [IO ()] 类型的列表。这可能会以不那么笨拙的方式重写,但是 现在 我们可以找到答案的核心,即使用 intersperse 在最终排序之前插入您的线程延迟[IO ()] 得到 IO [()].

import Data.List
let results = map process (apiLinks >>= simpleHttp)
    actions = intersperse (threadDelay 1) results 
in sequence actions

intersperse :: a -> [a] -> [a] 通过在其第二个元素的每个元素之间插入其第一个参数来工作。使用字符串的简单示例:

> intersperse '-' "abc"
"a-b-c"

其中一种方法是使用 forM_ 作为

...
do listOfContent <- z
   forM_ listOfContent $
         \content -> do pPrint $ (filteredTitles . onlyElems . parseXML) content
                        threadDelay 1000000