首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何折叠流数据?

如何折叠流数据?
EN

Stack Overflow用户
提问于 2017-08-17 03:59:24
回答 1查看 186关注 0票数 0

我正在尝试在Haskell中实现函数式反应流。我有一个相当简单的定义:

代码语言:javascript
复制
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。但我不知道如何在这种情况下做到这一点。用我简单的定义,这是可能的吗?或者我需要一些不同的东西?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-08-17 17:23:39

foldStream会跟踪状态。您必须将该状态放在某个地方,比如在IORef中。

代码语言:javascript
复制
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'
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45722021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档