我所说的一阶约束是什么意思
首先,我将解释我所说的对箭头的一阶约束的含义:由于箭头脱糖的方式,您不能在箭头 do-notation 中需要箭头命令的地方使用本地绑定名称。
下面是一个例子来说明:
proc x -> f -< x + 1
desugar toarr (\x -> x + 1) >>> f
和类似地desugar proc x -> g x -< ()
to 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
上面的定义不起作用,因为n
脱糖后不在范围内。
或者,类似地这个函数,其中对的第一部分SF
是要传递给的初始值accumHold
accumHold' :: SF (a,Event (a -> a)) -> a
accumHold' = ...
是否有一些我缺少的组合器或技巧?ArrowApply
或者没有实例就不可能编写这些定义?
tl; dr:是否可以在 yampa中定义accumHoldNoiseR :: (RandomGen g, Random a) => (a,a) -> g -> SF (Event (a -> a)) a
或定义?accumHold' :: SF (a,Event (a -> a)) -> a
注意:没有ArrowApply
for 的实例SF
。我的理解是,定义一个也没有意义。有关详细信息,请参阅“使用箭头编程”。