我如何手动推断实例const :: a - > a - >一个
Haskell类型变量被隐式量化。关键字forall
出现在::
之后。
例如,const
类型签名
const :: a -> b -> a
写为:
const :: forall a b. a -> b -> a
我的问题是:如何有效地
const :: forall a. a -> a -> a
从该定义中推断签名。我尝试使用从一阶逻辑中学到的概念,例如 universion消除,但从理论的角度看不到合理。
当然,这是有道理的,因为没有什么阻止b
与a
相同。
为什么我无法证明使用该推论规则是合理的?因为我无法在第二个量词上使用消除,因为变量会发生冲突。我无法用a
实例化b
。
Haskell type variables are implicitly quantified. The keywords forall
appear after ::
.
For example, const
type signature
const :: a -> b -> a
is written as:
const :: forall a b. a -> b -> a
My question is: how can I validly infer the signature
const :: forall a. a -> a -> a
from that definition. I tried using concepts I learned from first-order logic like Universal Elimination but couldn't justify from a theoretic standpoint.
Of course, it makes sense since nothing precludes b
being the same as a
.
Why I couldn't justify using that inference rule ? Because I can't use elimination on that second quantifier since variables would clash. I can't instantiate b
with a
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
考虑:
您不能推断(2)(1);如果可以的话,那意味着
const
始终的类型拟合forall a。 a - > a - >
(在(1)中还不明显,因为我们还没有应用足够的推理步骤)。但是我显然可以在const true'a'a''
的情况下使用const
,其中const
具有类型bool - > char - >布尔
。您能做的就是意识到(2)是(1)的实例化。
B
与A
一般不同,但是(如您所说),没有什么停止b
与a
在任何一种特定用法中都是同一件事。因此,从使用const
的上下文中,您可能可以推断特定用法具有类型for a。 a - > a - >
。例如,这发生在以下情况下:您还可以从
const :: forall a b中分辨出来。 a - > b - >仅一个
,如果您选择实例b
与a
相同 - > a - > 。我们始终有一个选项,因为承诺对 All 可能有效的类型可能的类型b
包括可能性子集,其中我们总是为b 就像我们为
a
所做的那样。为此,我们只需将
b
s替换为a
s(在我们正在实例化的量词范围内,但这是整个表达式)。您表示怀疑您可以这样做,因为变量会发生冲突,但是实例化一个变量与另一个变量相同,是我们在这里所做的 point 。它与简单地重命名变量和偶然地通过给出的变量相同的名称来更改表达式的情况并不相同;在这里,我们正在做出故意的选择,以检查特殊情况时,当它们不是 截然不同的情况下。但是,没有
const :: forall a - &gt的纯推理链; b - >
单独(没有任何使用何处的上下文)到const :: forall a。 a - > a - >
,因为当您进行更改时,您正在削弱/专业化const
;您选择将其限制为最通用类型的子类型。推理规则不会从(1)到(2)将您添加到选择将b
与a
相同的其他信息。 (用haskelly术语,这将是一个附加的a〜b
约束)Consider:
You can't infer (2) from (1); if you could that would imply that
const
always has a type fittingforall a. a -> a -> a
(and it just wasn't obvious in (1) because we hadn't applied enough inference steps yet). But I can obviously useconst
in situations likeconst True 'a'
, whereconst
has typeBool -> Char -> Bool
.What you can do is realise that (2) is an instantiation of (1).
b
is not the same asa
in general, but (as you said) there is nothing stoppingb
from being the same thing asa
in any one particular usage. So from a context whereconst
is used you may be able to infer that particular usage has typeforall a. a -> a -> a
. For example, that happens in:You can also tell from
const :: forall a b. a -> b -> a
alone that if you choose to instantiateb
to be the same asa
you getconst :: forall a -> a -> a
. We always have that as an option because the type promised to be valid for all possible typesb
, which includes the subset of possibilities where we always choose the same thing forb
as we do fora
.To do that we do simply replace the
b
s witha
s (within the scope of the quantifier that we're instantiating, but here that's the whole expression). You expressed doubt that you could do this because the variables would clash, but instantiating one variable to be the same as the other is the point of what we're doing here. It's not the same as simply renaming variables and accidentally changing the expression by giving variables the same name that were supposed to be distinct; here we are making the deliberate choice to examine the special case when they are not distinct.But there is no chain of pure inference from
const :: forall a -> b -> a
alone (without any context of where it is used) toconst :: forall a. a -> a -> a
, because when you make that change you are weakening/specialisingconst
; you're choosing to limit it to a subtype of its most general type. Inference rules won't get you from (1) to (2) without you adding the additional information that you are choosing to limitb
to be the same asa
. (In Haskelly terms, this would be an additionala ~ b
constraint)以下是作为评论开始的,并被搬到这里。
我认为您在这里是错的。实际上,您可以使用消除,变量冲突与普遍消除无关。 [从我从下面的来源中学到的,有时候发生冲突是相关的,有时不是。]
斯坦福大学逻辑概论第8章
作为
和
有了这个和通用介绍(UI)我会说
这会使
a在∀ba⇒(b⇒a)
等的主张中。
a
的量词 in∀Ba⇒(b⇒a)
,因此a
在(非现有)量词的范围内没有免费发生a
的 in∀ba⇒(b⇒a)
。The following started as comments and was moved here.
I think here you are simply wrong. You can in fact use elimination and the clash of variables is irrelevant for Universal Elimination. [From what I learned from the source below it seems to be the case that sometimes a clash is relevant and sometimes it is not.]
Chapter 8 of Stanford Introduction to Logic defines Universal Elimination (UE)
as
and
With this and Universal Introduction (UI) I would argue
This leaves the claims that
a is free for a in ∀b.a⇒(b⇒a)
, etc.There is no quantifier of
a
in∀b.a⇒(b⇒a)
, thereforea
does not occur free within the scope of (the non existing) quantifier ofa
in∀b.a⇒(b⇒a)
.