手工SML类型推断

时间:2017-09-04 21:27:08

标签: sml type-inference

您好我正在为我的决赛做好准备,考试中总会有ml类型推断。 即我们被要求写出类似这样的函数的类型:

setTimeout(function(){
  var camera = document.getElementById("cameraS");
  var tt = document.getElementById("ttS");

  var cameraPos = camera.getAttribute('position');
  var ttPos = tt.getAttribute('position');

  tt.setAttribute('position', cameraPos);
  tt.setAttribute('rotation', {'y': -90});
}, 5000);

fun ugh x y z = x z (y z);
val ugh = fn : ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c

然而,我尝试推断类型的所有方法我总是弄错了。 虽然网上有例子,但没有像这样的功能的例子。 有没有办法按照一些指导方针来弥补这种类型? 如果应用于第一个示例,则指南最佳。

1 个答案:

答案 0 :(得分:1)

是的,StackOverflow上有几个类型推断的示例:12345,...

  1. 要推断fun ugh x y z = x z (y z)的类型,您可以先说

    val ugh : 'a -> 'b -> 'c -> 'd
    

    因为它需要三个讨论的论点。您还可以看到x : 'a是两个咖喱参数的函数,y : 'b是一个参数的函数,而'd应该完全用'a来表示,'b'c

    因此,对于y的类型,请设置'b = 'c -> 'e,因为它需要z : 'c作为输入并返回我们尚未获得的类型。

    对于x的类型,请设置'a = 'c -> 'e -> 'f,因为它需要z : 'cy的输出作为输入并返回我们没有的类型t得到了。

    替换它们,根据需要添加括号,

    val ugh : ('c -> 'e -> 'f) -> ('c -> 'e) -> 'c -> 'f
    

    此时你可能想要重命名它们以便

    val ugh : ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c
    

    但你真的没必要。

    我在这里要考虑的唯一事情是x的类型取决于y的类型,所以我想首先确定它。

    1. 要推断fun doh x y z = z (x y) (y + 1)的类型,您可以类似地开始说

      val doh : 'a -> 'b -> 'c -> 'd
      

      因为它还需要三个参数。最容易设置'b = int,与第一个示例类似,您可以设置'a = int -> 'e,然后设置'c = 'e -> int -> 'd

      替换它们,根据需要添加括号,

      val doh : (int -> 'e) -> int -> ('e -> int -> 'd) -> 'd
      

      或稍微重命名后

      val doh : (int -> 'a) -> int -> ('a -> int -> 'b) -> 'b