0

Streaming 和 Haskell 的新手。

我一直在玩流媒体库,我对理解块部分特别感兴趣。例如:

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]

我怎样才能做到这一点?

4

1 回答 1

1

我们需要的是一个函数,它在块流的末尾插入一个延迟,并将该函数传递给maps.

delay在这里不起作用,因为它会在每个产生的值之间产生延迟。但是我们可以使用以下函数轻松完成Applicative

  S.print 
$ concats 
$ S.maps (\s -> s <* liftIO (threadDelay 1000000)) 
$ chunksOf 2 
$ S.each [1..10]

这里发生了什么?mapsStream. 在使用 获得的“分块流”中chunksOf,该基本函子本身就是一个Stream. 此外,转换必须保留Stream.

Streams 可以用函数排序,比如(>>=) :: Stream f m a -> (a -> Stream f m b) -> Stream f m b下一个流是否依赖于前一个流的最终结果,或者用函数排序,比如(<*) :: Stream f m a -> Stream f m b -> Stream f m a如果它不依赖。(<*)保留 first 的返回值Stream,这是我们在这种情况下想要的。

我们不想再产生任何元素,而只是引入延迟效果,所以我们干脆liftIO将效果放入Streammonad。


在 a 的每个产生值之后插入延迟的另一种方法Stream是使用无限延迟列表对其进行压缩

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)))
于 2018-06-10T08:03:00.147 回答