在Haskell中,我们可以编写以下数据类型:
data Fix f = Fix { unFix :: f (Fix f) }
类型变量f
具有* -> *
种类(即它是未知类型的构造函数)。因此,Fix
具有(* -> *) -> *
种类。我想知道Fix
是否是Hindley Milner类型系统中的有效类型构造函数。
从read on Wikipedia开始,Fix
似乎不是Hindley Milner类型系统中的有效类型构造函数,因为HM中的所有类型变量必须是具体的(即必须具有{{1}类型}})。确实如此吗?如果HM中的类型变量并不总是具体,那么HM会变得不可判断吗?
答案 0 :(得分:6)
重要的是类型构造函数是否构成一阶术语(没有类型构造函数表达式的约简行为)或更高阶的语言(在类型级别使用lambdas或类似结构)。
在前一种情况下,Fix
引起的约束总是以最一般的方式统一(假设我们坚持HM)。在每个c a b ~ t
等式中,t
必须解析为具有与c a b
相同形状的具体类型应用程序表达式,因为c a b
不可能减少到其他某个表达式。较高的参数不是问题,因为它们也只是以静态方式坐在那里,例如c [] ~ c f
由f = []
解决。
在后一种情况下,c a b ~ t
可能是也可能不是可解决的。在某些情况下,它由c = \a b -> t
解决,在其他情况下,没有最常见的统一者。
答案 1 :(得分:2)
更高的类型超越了基本的Hindley-Milner类型系统,但它们可以以相同的方式处理。
非常粗略地,HM解析表达式的语法树,将自由类型变量与每个子表达相关联,并根据类型变量根据类型变量生成一组等式约束。使用更高种类也可以做到这一点。
然后,通过统一解决约束。统一算法中的典型步骤是(伪随机数)
F
(请注意,这只是统一算法的部分。)
高于G
,F
是类型构造函数符号,而不是变量。在更高级别的统一中,我们需要考虑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在下面指出的那样。)