繁体   English   中英

在Haskell中使用RankNTypes进行类型检查

[英]Type checking with RankNTypes in Haskell

我试图了解Haskell中的RankNTypes并找到了这个例子:

check :: Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool
check f l1 l2 = f l1 == f l2

(如果我的理解是正确的,这相当于check :: forall bc d. Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool 。)

好的,到目前为止一切顺利。 现在,如果删除了明确的forall a ,GHC会产生以下错误:

Could not deduce (c ~ a)
from the context (Eq b)
[…]
Could not deduce (d ~ a)
from the context (Eq b)
[…]

删除嵌套的forall ,类型签名变为

check :: forall a b c d. Eq b => ([a] -> b) -> [c] -> [d] -> Bool

很容易l1为什么这会导致类型检查失败,因为l1l2应该有类型[a]让我们将它们传递给f ,但是为什么在指定f的类型时不是这种情况(forall a. [a] ->b) 事实上a只是在parens内部完全答案吗? 即类型检查器将接受

[c] -> b ~ (forall a. [a] -> b)
[d] -> b ~ (forall a. [a] -> b)

(编辑:修复。谢谢,博伊德!)

因为类型的函数(forall a. a -> b)可以列出任何列表吗?

f = \\xs -> ...用明确的Rank2量化写入时forall a. [a] -> b forall a. [a] -> b您可以将其视为新功能

f = Λa -> \xs -> ...

其中Λ是一个特殊的拉姆达,需要一个类型参数 ,以确定哪个特定类型a它会在函数体使用。 每次调用函数时都会应用此类型参数,就像在每次调用时应用正常的lambda绑定一样。 这就是GHC内部处理forall

在明确forall “d版本, f可以每次被调用所以时间施加到不同类型的参数a可以在每次将其解析为不同的类型,一旦c并一次d

在没有内部版本forall ,对于这种类型的应用程序a只发生一次,当check被调用。 所以每次调用f都必须使用相同的a 当然,这会失败,因为在不同类型的列表上调用f

很容易理解为什么这会导致类型检查失败,因为l1和l2应该有类型[a]让我们将它们传递给f,但是为什么在指定f的类型时不是这种情况(forall a。[a] - > b)?

因为类型(forall a. [a] -> B)可以与[C] -> B和(单独) [D] -> B统一。 但是,类型[A] -> B不能与[C] -> B[D] -> B统一。

事实上a只是在parens内部完全答案吗?

基本上。 当你在forall范围内时,你必须为每个类型变量选择一个特定的类型,但在外面你可以多次使用forall并且每次都选择不同的特定类型。

即类型检查器将接受

 [c] ~ (forall a. a -> b) [d] ~ (forall a. a -> b) 

因为类型的函数(forall a。a - > b)可以列出任何列表吗?

小心。 你似乎在那里失去了一些“[]”字符。 此外,你并没有完全正确的统一。 类型检查器将同时接受:

[C] -> B ~ (forall a. [a] -> B)
[D] -> B ~ (forall a. [a] -> B)

它也不会接受:

[C] -> B ~ [A] -> B
[D] -> B ~ [A] -> B

您可以在逆变场中重写通用量化,并在协变场中进行存在量化(在Haskell中不合法,但原则上)。

check' :: exists c' d'. forall b c d. Eq b
           => ([c'] -> b) -> ([d'] -> b) -> [c] -> [d] -> Bool

很明显这是有效的:对于c ~ Cd ~ D选择c' ~ Cd' ~ D ,那么函数就是简单

check'' :: forall b . Eq b => ([C] -> b) -> ([D] -> b) -> [C] -> [D] -> Bool

不确定这是否能回答你的问题,但这是查看排名2类型的一种方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM