新手到Streaming和Haskell这里。
我一直在玩streaming库,我对理解块部分特别感兴趣。例如:
S.print $ S.delay 1.0 $ concats $ chunksOf 2 $ S.each [1..10]
或者:
S.print $ concats $ S.maps (S.delay 1.0) $ chunksOf 2 $ S.each [1..10]
这里我可以在每个元素之后引入延迟,但我想要的是在每个块之后有一个延迟,在这种情况下是每秒元素的延迟。我尝试了这个,但没有编译:
S.print $ concats $ S.delay 1.0 $ chunksOf 2 $ S.each [1..10]
我怎样才能做到这一点?
答案 0 :(得分:1)
我们需要的是一个在块流末尾插入单个延迟的函数,并将该函数传递给maps
。
delay
在这里不起作用,因为它会在每个屈服值之间产生延迟。但我们可以使用Applicative
:
S.print
$ concats
$ S.maps (\s -> s <* liftIO (threadDelay 1000000))
$ chunksOf 2
$ S.each [1..10]
这里发生了什么? maps
将转换应用于Stream
的“基础仿函数”。在使用chunksOf
获得的“分块流”中,该基础仿函数本身 a Stream
。此外,转换必须保留Stream
的返回值。
(>>=) :: Stream f m a -> (a -> Stream f m b) -> Stream f m b
等函数对{p> Stream
进行排序,如果不是,则使用(<*) :: Stream f m a -> Stream f m b -> Stream f m a
等函数。 (<*)
保留第一个Stream
的返回值,这就是我们在这种情况下所需要的。
我们不想再产生任何元素,只是为了引入延迟效果,所以我们只需liftIO
效果Stream
monad。
在Stream
的每个屈服值之后插入延迟的另一种方法是zip it,延迟时间infinite list:
delay' :: MonadIO m => Int -> Stream (Of a) m r -> Stream (Of a) m r
delay' micros s = S.zipWith const s (S.repeatM (liftIO (threadDelay micros)))