我是OCaml的初学者和一般的函数式编程。如果我有一个表达式,除了将其输入顶层并编译之外,我该如何确定它的类型呢?
例如,如果我有
fun x -> fun (y, z) -> (x y) (z () )
我如何确定此表达式的类型?它是否涉及任何聪明,或者是否有一个简单的算法可以帮助我思考如何确定任何表达式的类型?
答案 0 :(得分:8)
不需要聪明。确实存在确定类型的算法。 Ocaml基于Hindley-Milner 类型系统。类型推断算法很少,您可以在文章中找到详细信息。至于你的例子,让我们尝试一点一点地搞清楚:
fun x -> fun (y, z) -> (x y) (z () )
整个表达式是一种函数,从某种类型A = typeof(x)
到B = typeof(fun(y, z) -> (x y) (z ()))
的类型。
z
的类型为() -> D
,因为它是使用()
调用并传递给x
因此,z ()
的类型为D
因此(x y)
的类型为(D -> E)
让C
成为y
x
的类型因此为C -> (D -> E)
且(x y) (z ())
的类型仅为E
了解x
,y
的类型和最后一个表达式,我们得出结论,整个表达式的类型为(C -> D -> E) -> C * (() -> D) -> E
答案 1 :(得分:3)
要搜索的字词是“Hindley-Milner type system”。您应该在网上找到大量资源,只需避开研究文章,这些文章可能是基本系统的任意复杂扩展。
有算法和类型系统。类型系统不是语法指导的:在任何步骤都必须选择遵循语法或instanciate / generalize。
“算法”是语法导向的(任何步骤都只适用一条规则),这就是它被称为“算法”的原因。这使它非常有效,尽管它仍然作为一组推理规则呈现。通过使用可变引用进行统一,可以提高效率。