问题
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, ...
To infer the type of
fun ugh x y z = x z (y z), you could start by saying thatval ugh : 'a -> 'b -> 'c -> 'dsince it takes three curried arguments. You can also see that
x : 'ais a function of two curried parameters and thaty : 'bis a function of one parameter, and that'dshould be expressed entirely in terms of'a,'band'c.So for the type of
y, set'b = 'c -> 'e, since it takesz : 'cas 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 takesz : 'cand the output ofyas 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 -> 'fAt that point you might want to rename them so you get
val ugh : ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'cbut you don't really have to.
The only things I had to think about here was the fact that the type of
xdepends on the type ofy, so I wanted to determine that first.
To infer the type of
fun doh x y z = z (x y) (y + 1), you could similarly start by saying thatval doh : 'a -> 'b -> 'c -> 'dsince it also takes three curried arguments. Most easily you can set
'b = int, and similar to the first example, you can set'a = int -> 'eand then'c = 'e -> int -> 'd.Replacing those, adding parentheses as needed, you get
val doh : (int -> 'e) -> int -> ('e -> int -> 'd) -> 'dor after a little renaming
val doh : (int -> 'a) -> int -> ('a -> int -> 'b) -> 'b
来源:https://stackoverflow.com/questions/46044213/sml-type-inference-by-hand