为什么输入中的箭头在 proc 块中的箭头命令中不可用?

Ste*_*and 1 haskell arrows

在学习箭头的过程中,我偶然发现了一个随着时间的推移并没有变得更清晰的点:

从 John Hughes 的论文“Generalizing Monads To Arrows”中,我注意到下面的情况(情况 I)是不可能的,因为参数中的箭头 f不能在箭头过程的本地范围内使用。

-- case I
proc (f,x) -> returnA <- f -< x     --- here the f is illegal   
Run Code Online (Sandbox Code Playgroud)

如果我们otherArrow在其他地方定义了另一个箭头 ,我们可以这样做:

-- case II
proc (f,x) -> returnA <- otherArrow -< x
Run Code Online (Sandbox Code Playgroud)

我理解需要类似-<没有应用箭头才能应用于x其输入。所以我们用-<它来实现这一点(案例二)。

但我不明白无法使用块参数中给出的箭头的原因proc。(fproc (f,x)案例 I 中)。

而我的不理解又和一个经常使用的术语发生了冲突:箭头命令。Papers 坚持认为它并不等同于 Haskell 表达式,并且 Haskell 类型系统不适合使箭头命令成为语言中的一流命令。

我再次不明白是什么事实/属性使它不可能在 Haskell 类型系统中成为一流的。理解这种不可能背后的原因似乎是我需要的洞察力。

鉴于罗斯帕特森论文中的语法:

exp ::=   ...
        | proc pat -> cmd

cmd ::=   exp -< exp
        | form exp cmd1 ... cmdn 
        | cmd1 op cmd2
        | K pat -> cmd
        | (cmd)
Run Code Online (Sandbox Code Playgroud)

从这个语法中我不明白这种不可能的原因。

但根据翻译规则我们有:

proc p -> e1 -< e2 = arr $ \p -> e2 >>> e1 -- if intersect Vars(p) and Vars (e1) is empty 
                   = arr $ \p -> (e1,e2) >>> app -- otherwise
Run Code Online (Sandbox Code Playgroud)

p在第一个分支中,我们看到变量 in和 in的交集e1应该为空...这个变量范围限制是箭头命令的主要特征吗?我的意思是导致无法首先创建箭头命令的原因哈斯克尔级?

正如我所问的,我的头脑对箭头命令箭头组合(使用像>>>这样的运算符,最终产生箭头本身)和简单的箭头之间没有太大区别。

lef*_*out 5

事实上,语法似乎太弱,无法指出这个问题。

\n\n

您基本上已经准确地发现了 \xe2\x80\x9cArrow 不如 Monad\xe2\x80\x9d 强大的原因。(FTR,我不喜欢这种比较 \xe2\x80\x93 箭头是一种抽象,它来自与 monad 根本不同的方向,只有它们与类别一起使用时恰好能够支持大多数 monad 操作Kleisli。)

\n\n

proc符号是一种作弊。它允许您为 \xe2\x80\x9cvariables\xe2\x80\x9d 指定名称,这些名称不一定对应于实际值(即也可以与 lambda 绑定的值)。只要您只使用 右侧的那些就可以了-<,脱糖器将知道如何将其转换为扇出/投影操作。特别是,您的caseII脱糖剂为

\n\n
   proc (f,x) -> returnA <- otherArrow -< x\n\xe2\x89\xa1  proc   fx -> returnA <- otherArrow -< snd fx\n\xe2\x89\xa1                 id  <<< otherArrow <<< arr snd\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是在 中caseII,您尝试绑定一个虚拟变量f,该变量本身代表要在链中使用的箭头。这是一个问题,因为在我们已经拥有它的情况下,您无法构建通过此 \xe2\x80\x9cvariable\xe2\x80\x9d 进行管道传输的链!

\n