我正在尝试在Haskell中实现函数式反应流。我有一个相当简单的定义:
data Observer a = Observer { next :: a -> IO () }
data Stream a = Stream { subscribe :: Observer a -> IO () }
instance Functor Stream where
fmap = mapStream
mapStream :: (a -> b) -> Stream a -> Stream b
mapStream f Stream{ subscribe=s } = Stream {
subscribe = \Observer{ next=n } -> s Observer{ next = \a -> n $ f a }
}
fromArray :: [a] -> Stream a
fromArray arr = Stream {
subscribe = \Observer{ next=n } -> forM_ arr n
}这对于像上面的fmap这样的简单运算符很有效。我的问题是,我该如何实现foldStream?我不能改变值,所以我必须用一个新的种子值递归地调用foldStream。但我不知道如何在这种情况下做到这一点。用我简单的定义,这是可能的吗?或者我需要一些不同的东西?谢谢。
发布于 2017-08-17 17:23:39
foldStream会跟踪状态。您必须将该状态放在某个地方,比如在IORef中。
import Data.IORef
foldStream :: (a -> b -> b) -> b -> Stream a -> Stream b
foldStream f z source = Stream $ \observer -> do
ref <- newIORef z
subscribe source $ Observer $ \a -> do
b <- readIORef ref
let b' = f a b
writeIORef ref b'
next observer b'https://stackoverflow.com/questions/45722021
复制相似问题