提示SML类型推断

时间:2016-06-05 10:08:26

标签: sml type-inference

我是SML的新手,我正在尝试使用SML类型参考。我试图扣除以下类型:

a)fun add42 x =x+42
b)fun comp F G = let fun C x = G(F(x)) in C end
c)fun compA42 x = comp add42 x
d)val foo = compA42 add42
e)fun compCompA42 x = comp compA42 x

我认为前四个解决方案是:

a)int->int
b)(a->b)->(b->c)->a->c
c)(int->a)->int->a
d)int->int

但我对最后一个感到困惑。 是否有任何提示可以扣除最后一种类型??

非常感谢。

1 个答案:

答案 0 :(得分:2)

让我们一步一步地手动完成:

fun compCompA42 x = comp compA42 x
  1. 这是一个函数,因此compCompA42的类型为α -> β
  2. compCompA42的返回值必须与comp compA42 x的类型相同,即β = typeof(comp compA42 x)
  3. 我们现在已经是comp的最常规类型:

    (a -> b) -> (b -> c) -> a -> c

  4. 现在,我们需要将其专门用于a -> b = typeof(compA42)(b -> c) = α的情况:

    1. a -> b = typeof(compA42) = (int -> d) -> int -> d。从这个等式可以得出a = int -> db = int -> d

    2. 所以,α = b -> c = (int -> d) -> cβ = typeof(comp compA42 x) = a -> c = (int -> d) -> c

    3. 最后,我们compCompA42的最常见类型是

      α -> β = ((int -> d) -> c) -> (int -> d) -> c

    4. <小时/> 注意你总是可以让一些SML解释器(例如,smlnj)显示你的类型:

      - fun compCompA42 x = comp compA42 x;
      val compCompA42 = fn : ((int -> 'a) -> 'b) -> (int -> 'a) -> 'b
      

      它与我们手动设置的类型相同(只需将d重命名为'a,将c重命名为'b。)