为什么输入中的箭头在 proc 块中的箭头命令中不可用?
Why arrows in input are not useable in arrow commands in a proc block?
在我学习箭头的过程中,我偶然发现了一点,但随着时间的推移并没有变得更加清晰:
来自 John Hughes 的论文 "Generalizing Monads To Arrows",我注意到下面的这个(案例 I)是不可能的,因为参数中的 arrow f
不能在箭头过程的局部范围内使用。
-- case I
proc (f,x) -> returnA <- f -< x --- here the f is illegal
如果我们在其他地方定义了另一个箭头 otherArrow
,我们可以这样做:
-- case II
proc (f,x) -> returnA <- otherArrow -< x
我理解 -<
的必要性,就像没有应用箭头以便将 x
应用到它的输入。所以我们使用-<
来实现这个(案例二)。
但我看不出无法使用 proc
块参数中给出的箭头的原因。 (f
in proc (f,x)
案例一)。
而我的不理解与一个经常使用的术语相冲突:arrow command。论文坚持认为它不等同于 haskell 表达式,并且 Haskell 类型系统不适合在语言中先制作箭头命令-class。
同样,我没有看到什么是 fact/the 属性 使得它不可能在 Haskell 类型系统中成为 first-class。理解这种不可能背后的原因似乎是我需要的洞察力。
根据 Ross Paterson 论文中的语法:
exp ::= ...
| proc pat -> cmd
cmd ::= exp -< exp
| form exp cmd1 ... cmdn
| cmd1 op cmd2
| K pat -> cmd
| (cmd)
从这个语法我不明白不可能的原因。
但是从翻译规则我们有:
proc p -> e1 -< e2 = arr $ \p -> e2 >>> e1 -- if intersect Vars(p) and Vars (e1) is empty
= arr $ \p -> (e1,e2) >>> app -- otherwise
在第一个分支中,我们看到 p
和 e1
中变量的交集应该是空的......这个变量范围限制是箭头命令的主要特征吗,我的意思是什么导致无法在 Haskell 中首先制作箭头命令的原因 - class ?
正如我所问的,我认为 arrow-command 和 composition-of-arrows 之间没有太大区别(with像 >>> 这样的运算符,它最终会产生一个箭头本身)和一个简单的 arrow.
的确,语法似乎太弱了,无法指出这个问题。
您基本上已经准确地发现了“Arrow 不如 Monad 强大”的原因。 (FTR,我不喜欢这种比较——箭头是一种抽象,它来自与 monad 根本不同的方向,只有在与 Kleisli
类别一起使用时它们才恰好能够支持大多数 monad 操作。)
proc
符号是作弊。它允许你给“变量”命名,这些变量根本不一定对应于实际值(即,也可以用 lambda 绑定的东西)。只要您只使用 -<
右侧的那些就没问题,脱糖器将知道如何将其转换为 fanout/projection 操作。特别是,您的 caseII
脱糖为
proc (f,x) -> returnA <- otherArrow -< x
≡ proc fx -> returnA <- otherArrow -< snd fx
≡ id <<< otherArrow <<< arr snd
但在 caseII
中,您尝试绑定一个虚拟变量 f
,它本身表示要在链中使用的箭头。这是一个问题,因为如果我们已经拥有它,您就无法建立通过该“变量”进行传输的链!
在我学习箭头的过程中,我偶然发现了一点,但随着时间的推移并没有变得更加清晰:
来自 John Hughes 的论文 "Generalizing Monads To Arrows",我注意到下面的这个(案例 I)是不可能的,因为参数中的 arrow f
不能在箭头过程的局部范围内使用。
-- case I
proc (f,x) -> returnA <- f -< x --- here the f is illegal
如果我们在其他地方定义了另一个箭头 otherArrow
,我们可以这样做:
-- case II
proc (f,x) -> returnA <- otherArrow -< x
我理解 -<
的必要性,就像没有应用箭头以便将 x
应用到它的输入。所以我们使用-<
来实现这个(案例二)。
但我看不出无法使用 proc
块参数中给出的箭头的原因。 (f
in proc (f,x)
案例一)。
而我的不理解与一个经常使用的术语相冲突:arrow command。论文坚持认为它不等同于 haskell 表达式,并且 Haskell 类型系统不适合在语言中先制作箭头命令-class。
同样,我没有看到什么是 fact/the 属性 使得它不可能在 Haskell 类型系统中成为 first-class。理解这种不可能背后的原因似乎是我需要的洞察力。
根据 Ross Paterson 论文中的语法:
exp ::= ...
| proc pat -> cmd
cmd ::= exp -< exp
| form exp cmd1 ... cmdn
| cmd1 op cmd2
| K pat -> cmd
| (cmd)
从这个语法我不明白不可能的原因。
但是从翻译规则我们有:
proc p -> e1 -< e2 = arr $ \p -> e2 >>> e1 -- if intersect Vars(p) and Vars (e1) is empty
= arr $ \p -> (e1,e2) >>> app -- otherwise
在第一个分支中,我们看到 p
和 e1
中变量的交集应该是空的......这个变量范围限制是箭头命令的主要特征吗,我的意思是什么导致无法在 Haskell 中首先制作箭头命令的原因 - class ?
正如我所问的,我认为 arrow-command 和 composition-of-arrows 之间没有太大区别(with像 >>> 这样的运算符,它最终会产生一个箭头本身)和一个简单的 arrow.
的确,语法似乎太弱了,无法指出这个问题。
您基本上已经准确地发现了“Arrow 不如 Monad 强大”的原因。 (FTR,我不喜欢这种比较——箭头是一种抽象,它来自与 monad 根本不同的方向,只有在与 Kleisli
类别一起使用时它们才恰好能够支持大多数 monad 操作。)
proc
符号是作弊。它允许你给“变量”命名,这些变量根本不一定对应于实际值(即,也可以用 lambda 绑定的东西)。只要您只使用 -<
右侧的那些就没问题,脱糖器将知道如何将其转换为 fanout/projection 操作。特别是,您的 caseII
脱糖为
proc (f,x) -> returnA <- otherArrow -< x
≡ proc fx -> returnA <- otherArrow -< snd fx
≡ id <<< otherArrow <<< arr snd
但在 caseII
中,您尝试绑定一个虚拟变量 f
,它本身表示要在链中使用的箭头。这是一个问题,因为如果我们已经拥有它,您就无法建立通过该“变量”进行传输的链!