首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Iteratees和FRP之间有什么联系?

Iteratees和FRP之间有什么联系?
EN

Stack Overflow用户
提问于 2012-12-18 03:20:39
回答 2查看 902关注 0票数 19

在我看来,这两个想法之间有很强的联系。我的猜测是,如果有一种方法可以用迭代器来表示任意图,那么FRP可以用迭代器来实现。但afaik只支持链状结构。

谁能解释一下这件事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-18 03:59:45

情况正好相反。AFRP和流处理之间有很强的联系。实际上,AFRP是流处理的一种形式,您可以使用这个习惯用法来实现非常类似于管道的东西:

代码语言:javascript
复制
data Pipe m a b =
    Pipe {
      cleanup :: m (),
      feed    :: [a] -> m (Maybe [b], Pipe m a b)
    }

这是在Netwire中找到的导线类别的扩展。它接收下一段输入,并在停止生产时不返回任何内容。使用此选项,文件读取器将具有以下类型:

代码语言:javascript
复制
readFile :: (MonadIO m) => FilePath -> Pipe m a ByteString

管道是一个应用型函数族,所以要对流元素应用一个简单的函数,您可以只使用fmap

代码语言:javascript
复制
fmap (B.map toUpper) . readFile

为了您的方便,它也是一个支持程序的家庭。

最有趣的特性是,这是一个可供选择的函数族。这允许您路由周围的流,并允许多个流处理器在放弃之前“尝试”。这可以扩展到一个完整的解析库,它甚至可以使用一些静态信息进行优化。

票数 13
EN

Stack Overflow用户

发布于 2012-12-18 06:09:25

您可以使用流处理器实现有限形式的FRP。例如,使用pipes库,您可以定义一个事件源:

代码语言:javascript
复制
mouseCoordinates :: (Proxy p) => () -> Producer p MouseCoord IO r

..。您也可以类似地定义一个图形处理程序,该处理程序接受鼠标坐标并更新画布上的光标:

代码语言:javascript
复制
coordHandler :: (Proxy p) => () -> Consumer p MouseCoord IO r

然后,您可以使用组合将鼠标事件连接到处理程序:

代码语言:javascript
复制
>>> runProxy $ mouseCoordinates >-> coordHandler

它会按照你所期望的方式运行。

正如您所说,这对于单个阶段链很有效,但是对于更任意的拓扑呢?事实证明,由于pipes的中央Proxy类型是monad transformer,您只需将代理monad transformer嵌套在自身之上,即可对任意拓扑进行建模。例如,下面是如何压缩两个输入流的方法:

代码语言:javascript
复制
zipD
 :: (Monad m, Proxy p1, Proxy p2, Proxy p3)
 => () -> Consumer p1 a (Consumer p2 b (Producer p3 (a, b) m)) r
zipD () = runIdentityP $ hoist (runIdentityP . hoist runIdentityP) $ forever $ do
    a <- request ()               -- Request from the outer Consumer
    b <- lift $ request ()        -- Request from the inner consumer
    lift $ lift $ respond (a, b)  -- Respond to the Producer

这就像是一个curried函数。您可以按顺序将其部分应用于每个输入,然后可以在完全应用时运行它。

代码语言:javascript
复制
-- 1st application
p1 = runProxyK $ zipD   <-< fromListS [1..]

-- 2nd application
p2 = runProxyK $ p2     <-< fromListS [4..6]

-- 3rd application
p3 = runProxy  $ printD <-< p3

它的运行方式完全符合您的预期:

代码语言:javascript
复制
>>> p3
(1, 4)
(2, 5)
(3, 6)

此技巧适用于任何拓扑。您可以在Control.Proxy.Tutorial的“分支、压缩和合并”小节中找到有关这方面的更多详细信息。特别是,您应该查看它用作示例的fork组合器,该组合器允许您将流拆分为两个输出。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13920695

复制
相关文章

相似问题

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