SML type inference by hand

淺唱寂寞╮ 提交于 2019-12-11 04:14:41

问题


Hello I am getting ready for my finals and there is always ml type inference on the exams . i.e. we are asked to write the type of a function like this one :

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

or

fun doh x y z = z (x y ) (y + 1);
val doh = fn : (int -> 'a) -> int -> ('a -> int -> 'b) -> 'b

However all the ways I am trying to infer the type I always get it wrong . Although there are examples online there are no examples for functions like that . Is there a way to make up the type following some guidelines ? The guidelines would be best if applied to the first example .


回答1:


Yes, there are several examples of type inference by hand on StackOverflow: 1, 2, 3, 4, 5, ...

  1. To infer the type of fun ugh x y z = x z (y z), you could start by saying that

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

    since it takes three curried arguments. You can also see that x : 'a is a function of two curried parameters and that y : 'b is a function of one parameter, and that 'd should be expressed entirely in terms of 'a, 'b and 'c.

    So for the type of y, set 'b = 'c -> 'e, since it takes z : 'c as input and returns something of a type that we haven't gotten to yet.

    And for the type of x, set 'a = 'c -> 'e -> 'f, since it takes z : 'c and the output of y as input and returns something of a type that we haven't gotten to yet.

    Replacing those, adding parentheses as needed, you get

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

    At that point you might want to rename them so you get

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

    but you don't really have to.

    The only things I had to think about here was the fact that the type of x depends on the type of y, so I wanted to determine that first.


  1. To infer the type of fun doh x y z = z (x y) (y + 1), you could similarly start by saying that

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

    since it also takes three curried arguments. Most easily you can set 'b = int, and similar to the first example, you can set 'a = int -> 'e and then 'c = 'e -> int -> 'd.

    Replacing those, adding parentheses as needed, you get

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

    or after a little renaming

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


来源:https://stackoverflow.com/questions/46044213/sml-type-inference-by-hand

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!