Reputation: 21875
Consider the following code :
fun g(a) =
let fun h(b)=g(a)
in h end;
When I run it in SML , I get :
- fun g(a) =
= let fun h(b)=g(a)
= in h end;
stdIn:55.5-57.10 Error: right-hand-side of clause doesn't agree with function re
sult type [circularity]
expression: 'Z -> 'Y
result type: 'Y
in declaration:
g = (fn a => let val <binding> in h end)
I can't understand the problem here : g(a)
return h
, but
I don't see any specific return value in the declaration fun g(a)
(i.e. nothing like
fun g(a):int
) , so why the error ?
Thanks
Upvotes: 1
Views: 3634
Reputation: 1981
ML type inference system first identified your function g as an expression which takes a 'Z and returns 'Y. But then it sees that the result type of g is just 'Y and also which is the result type of earlier binding h. It can be expected to see binding of type Z -> Z->Y . However your function closure has an environment which is itself. So it is like binding g like this.
fun g a= g
ML type inference can not guess the types if your closure has an environment which is also itself.
You can declare these functions as follows.
fun g(a) =
let
fun h(b)=g(a)
in
h(a)
end;
It is like
fun g a = g a
This time your closure has just a body of itself. But it makes no sense...just an example of why you are getting a circularity error.
Upvotes: 1
Reputation: 66459
Since g
has one parameter it has type 'X -> 'Y
.
h(b) = g(a)
means that h
and g
must have the same result type 'Y
,
and h
has the type 'Z -> 'Y
.
Thus, g(x)
, for any x of type 'X
, must have type 'Y
.
But the return value of g(x)
is h
, which has type 'Z -> 'Y
.
This means that 'Y
must be the same type as 'Z -> 'Y
, which is impossible.
As SML says, 'Z -> 'Y
(the type of h
) doesn't agree with 'Y
(the type of g(a)
).
If you try to work it out by hand, you'll find that
g 1
would be a function h
such that
h 3
is the value of
g 1
which is a function h
such that...
and so on, indefinitely.
Upvotes: 3