如何解决箭头的一阶约束?

Jas*_*git 7 haskell arrows yampa

我的意思是一阶约束

首先,我将通过箭头的一阶约束来解释我的意思:由于箭头desugar的方式,你不能使用箭头命令中预​​期箭头命令的本地绑定名称.

这是一个例子来说明:

proc x -> f -< x + 1desugars到arr (\x -> x + 1) >>> f并且类似地proc x -> g x -< ()将desugar到arr (\x -> ()) >>> g x,其中第二x是自由变量.该GHC用户指南解释了这一点,并说,当你的箭也是一个单子,你可以做的实例ArrowApply,并使用app来解决这个问题.proc x -> g x -<< ()变得像arr (\x -> (g x, ())) >>> app.

我的问题

Yampa accumHold用这种类型定义函数:a -> SF (Event (a -> a)) a.由于这个箭头的一阶限制,我正在努力编写以下函数:

accumHoldNoiseR :: (RandomGen g, Random a) => (a,a) -> g -> SF (Event (a -> a)) a
accumHoldNoiseR r g = proc f -> do
  n <- noiseR r g -< ()
  accumHold n -< f
Run Code Online (Sandbox Code Playgroud)

上面的定义不起作用,因为n在desugaring之后不在范围内.

或者,类似于此函数,其中对的第一部分SF是传递给的初始值accumHold

accumHold' :: SF (a,Event (a -> a)) -> a
accumHold' = ...
Run Code Online (Sandbox Code Playgroud)

是否有一些我错过的组合或技巧?或者,如果没有ArrowApply实例,是否无法编写这些定义?

tl; dr:是否有可能定义accumHoldNoiseR :: (RandomGen g, Random a) => (a,a) -> g -> SF (Event (a -> a)) aaccumHold' :: SF (a,Event (a -> a)) -> a在yampa?

注意:没有ArrowApplyfor的实例SF.我的理解是,定义一个也没有意义.有关详细信息,请参见"使用箭头编程".

And*_*ewC 3

这是一个理论上的答案。查看Roman Cheplyaka对这个问题的回答,它更多地涉及您想要实现的目标的实际细节。


超出范围的原因n是,要使其在此处使用的范围内,您将拥有 monad 的等效项bind>>=来自 monad 的等效项。它使用前一个计算的结果作为下一个计算的功能输入,这使得某些东西像 monad 一样强大。

因此,当您可以创建 ArrowApply 实例时,您可以将其n作为函数参数提供给后续箭头。

Chris Kuklewicz 在他的评论中正确指出,这-<<将纳入n范围 - 它也使用app,因此您需要一个 ArrowApply 实例。

概括

除非您使用 ArrowApply,否则不会。这就是 ArrowApply 的用途。