【发布时间】:2021-07-22 07:55:10
【问题描述】:
我正在为一种玩具语言实现Algorithm W。我遇到了一个我想象会键入检查的案例,但没有。我在 Haskell 中尝试过同样的方法,但令我惊讶的是它在那里也不起作用。
> (\id -> id id 'a') (\x -> x)
Couldn't match type ‘Char -> t’ with ‘Char’
Expected type: Char -> t
Actual type: (Char -> t) -> Char -> t
我认为id 是多态的,但似乎不是。请注意,如果 id 使用 let 定义而不是作为参数传递,则此示例有效:
let id x = x in id id 'a'
'a'
:: Char
查看算法 W 的推理规则时,这是有道理的,因为它有一个 let 表达式的泛化规则。
但我想知道这是否有任何原因?不能把函数参数也泛化成多态使用吗?
【问题讨论】:
-
不是
(\x -> x)是或不是多态的,而是id的绑定。let id = \x -> x in id id 1有效。与\x -> x相同,但let的 绑定具有多态类型。它被称为“let多态性”。 -
@WillNess 很好的澄清。在发布接受的答案之前,我没有意识到这一点。我会相应地更新问题。
标签: algorithm haskell type-systems hindley-milner