Haskell - вставка потока dealy между результатами функции Prelude.sequence - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть некоторый код, похожий на этот

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

, где apiLinks - список ссылок, который вызывает некоторую функцию API.

У меня также есть эта функция

  z = sequence listOfIOByteStrings

sequence имеет этот тип sequence :: Monad m => t (ma) -> m (ta)

Что я хочу сделать, это добавить задержку потокамежду оценками ByteString.

Я думаю об использовании threadDelay threadDelay :: Int -> IO ()

Это то, что яя делаю в конечном итоге

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

, где

parseXML :: ByteString -> [Content]

onlyElems :: [Content] -> [Элемент]

и

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...

I 'Я не уверен, как мне поступить так.

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Один из способов сделать это - использовать forM_ как

...
do listOfContent <- z
   forM_ listOfContent $
         \content -> do pPrint $ (filteredTitles . onlyElems . parseXML) content
                        threadDelay 1000000
0 голосов
/ 19 декабря 2018

Я не совсем слежу за всеми типами в вашем конвейере, поэтому считаю это черновым наброском, который можно конкретизировать.Во-первых, вы не хотите звонить sequence слишком рано.Сохраните ваш список IO Bytestring значений на данный момент.

Далее вам нужна некоторая функция (определенная в терминах filteredTitles . onlyElems . parseXML), которая принимает single Bytestring и возвращает 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"
...