我们可以在Hindley Milner类型系统中的构造函数位置中使用类型变量吗?

时间:2016-05-06 04:38:44

标签: haskell functional-programming ocaml type-inference hindley-milner

在Haskell中,我们可以编写以下数据类型:

data Fix f = Fix { unFix :: f (Fix f) }

类型变量f具有* -> *种类(即它是未知类型的构造函数)。因此,Fix具有(* -> *) -> *种类。我想知道Fix是否是Hindley Milner类型系统中的有效类型构造函数。

read on Wikipedia开始,Fix似乎不是Hindley Milner类型系统中的有效类型构造函数,因为HM中的所有类型变量必须是具体的(即必须具有{{1}类型}})。确实如此吗?如果HM中的类型变量并不总是具体,那么HM会变得不可判断吗?

2 个答案:

答案 0 :(得分:6)

重要的是类型构造函数是否构成一阶术语(没有类型构造函数表达式的约简行为)或更高阶的语言(在类型级别使用lambdas或类似结构)。

在前一种情况下,Fix引起的约束总是以最一般的方式统一(假设我们坚持HM)。在每个c a b ~ t等式中,t必须解析为具有与c a b相同形状的具体类型应用程序表达式,因为c a b不可能减少到其他某个表达式。较高的参数不是问题,因为它们也只是以静态方式坐在那里,例如c [] ~ c ff = []解决。

在后一种情况下,c a b ~ t可能是也可能不是可解决的。在某些情况下,它由c = \a b -> t解决,在其他情况下,没有最常见的统一者。

答案 1 :(得分:2)

更高的类型超越了基本的Hindley-Milner类型系统,但它们可以以相同的方式处理。

非常粗略地,HM解析表达式的语法树,将自由类型变量与每个子表达相关联,并根据类型变量根据类型变量生成一组等式约束。使用更高种类也可以做到这一点。

然后,通过统一解决约束。统一算法中的典型步骤是(伪随机数)

F

(请注意,这只是统一算法的部分。)

高于GF是类型构造函数符号,而不是变量。在更高级别的统一中,我们需要考虑G(f t1 ... tn := g s1 ... sk) = | n/=k -> fail | otherwise -> { f := g , t1 := s1 , ... , tn := sn } 也是变量。 我们可以尝试以下规则:

f Int ~ Either Bool Int

但是等等!以上是不正确的,因为例如f ~ Either Bool时必须统一n/=k。因此,我们还需要考虑(f t := g s) = { f := g , t := s } (F := G) = -- rule for atomic terms | F /= G -> fail | otherwise -> {} 的情况。通常,一个简单的规则集是

$ python3
Python 3.5.0 |Anaconda 2.4.0 (x86_64)| (default, Oct 20 2015, 14:39:26)
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import got
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/viach/Downloads/GetOldTweets-python-master/got/__init__.py", line 1, in <module>
    import models
ImportError: No module named 'models'
>>> ^C
KeyboardInterrupt

$ python2
Python 2.7.10 (default, Aug 22 2015, 20:33:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import got

(同样,这只是统一算法的部分。其他案例也必须处理,正如Andreas Rossberg在下面指出的那样。)