ArrowLoop如何运作?还有,mfix?

dan*_*raj 30 monads haskell arrows

我现在对箭头机械的其余部分感到相当舒服,但我不知道循环是如何工作的.这对我来说似乎很神奇,这对我的理解不利.我也很难理解mfix.当我查看一个rec在块procdo块中使用的代码时,我感到困惑.使用常规的monadic或箭头代码,我可以逐步完成计算并保持头脑中正在发生的事情.当我到达时rec,我不知道要保留什么图片!我卡住了,我无法推断这样的代码.

我试图解决的例子来自Ross Paterson关于箭头的论文,关于电路的论文.

counter :: ArrowCircuit a => a Bool Int
counter = proc reset -> do
        rec     output <- returnA -< if reset then 0 else next
                next <- delay 0 -< output+1
        returnA -< output
Run Code Online (Sandbox Code Playgroud)

我假设如果我理解这个例子,我将能够理解循环,这将是理解mfix的一个很好的方法.他们对我的感觉基本上是一样的,但也许我有一个微妙的缺失?无论如何,我真正想要的是这些代码片段的操作画面,所以我可以在头脑中像"常规"代码一样介绍它们.

编辑:感谢Pigworker的回答,我开始考虑rec和满足要求.取counter实施例中,REC块的第一行需要一个叫做值output.我想象这可以创建一个盒子,标记它output,并要求rec块填充那个盒子.为了填充该框,我们为returnA提供一个值,但该值本身需要另一个值,称为next.为了使用这个值,必须要求rec块中的另一行,但是现在要求在rec块中的哪个并不重要.

所以我们转到下一行,我们发现标有框next,我们要求另一个计算填充它.现在,这个计算需要我们的第一个盒子!所以我们给它一个盒子,但它里面没有任何价值,所以如果这个计算需要内容output,我们就会遇到无限循环.幸运的是,延迟占用了盒子,但产生了一个值而没有查看盒子内部.这填补next,然后允许我们填补output.现在output已经填充,当处理该电路的下一个输入时,前一个output框将具有其值,准备被要求以产生下一个next,从而产生下一个output.

听上去怎么样?

pig*_*ker 25

在这段代码中,它们的关键部分是块中的delay 0箭头rec.要了解它是如何工作的,有必要将值视为随时间和时间变化而切成片.我认为切片是"天".该rec块解释了每天的计算是如何工作的.它是按价值而非因果顺序组织的,但如果我们小心的话,我们仍然可以追踪因果关系.至关重要的是,我们必须确保(没有类型的任何帮助)每天的工作依赖于过去而不是未来.为期一天的delay 0购买我们的时间在这方面:它一天之后就将其输入信号,给予0延迟的输入信号的值照顾的第一天是"明天的next".

rec     output <- returnA -< if reset then 0 else next
        next <- delay 0 -< output+1
Run Code Online (Sandbox Code Playgroud)

因此,看看箭头和它们的输出,我们将在今天 发布,output明天 会发布next.看看投入,我们依赖于今天 resetnext价值观.很明显,我们可以在没有时间旅行的情况下从这些输入中提供这些输出.这output是今天的next数字,除非我们reset为0; 明天,这个next号码是今天的继承者output.今天的next价值因此来自昨天,除非昨天没有,在这种情况下它是0.

在较低的层次上,由于Haskell的懒惰,整个设置都有效.Haskell通过需求驱动的策略进行计算,因此如果存在一个尊重因果关系的连续顺序,Haskell就会找到它.在这里,delay建立这样的订单.

但请注意,Haskell的类型系统在确保存在此类订单方面几乎没有帮助.你可以自由地使用循环来完全废话!所以你的问题远非微不足道.每次阅读或编写此类程序时,您都需要考虑"这可能如何工作?".您需要检查是否正确使用了delay(或类似的)以确保仅在可以计算信息时才需要信息.请注意,构造函数,尤其(:)可以像延迟一样:计算列表的尾部并不罕见,显然给出了整个列表(但只注意检查头部).与命令式编程不同,懒惰的功能风格允许您围绕事件序列以外的概念组织代码,但这是一种需要更细微的时间意识的自由.

  • 这里的懒惰可能就像"更好地请求宽恕而不是许可"这一原则,其中不终止的可能性在小字体中是一种脚注,说不,如果你陷入困境,你实际上不会被宽恕. (3认同)
  • @CA McCann重新宽恕与许可,工作正在出现(例如我自己的http://www.e-pig.org/epilogue/?p=186),以通过一个类型系统获得更多关于懒惰的处理模态类型算子捕获"明天的价值"的概念.我们可能会设法通过许可系统来解释懒惰的典型用法,而不是用脚注说"但不要搞砸".我很乐观. (3认同)