I’d like some help with understanding how type inference affects the following code, which comes from a previous question (which after some thoughts I’ve simplified to the following):
type 'a result =
| Succ of 'a
| Fail
let first f = function
| Succ c -> let res = f c in Succ res
| fail -> fail
let second f = function
| Succ c -> let res = f c in Succ res
| Fail -> Fail
My question is: why does f in first have type ('a -> 'a) but f in second have type ('a -> 'b)?
You can see it here.
>Solution :
- The two occurrences of
FailinFail -> Failinsecondare treated as two distinct values, and thus are allowed to have different types'a resultand'b result, but - The two occurrences of
failinfail -> failinfirstare treated as the same value, and thus cannot change types.
Or at least the type inference system doesn’t allow it to change types. I’m not sure whether that’s a specification or a quirk of this particular interpreter.
As food for thought, a third version:
let third f r = match r with
| Succ c -> Succ (f c)
| _ -> r
You and I know that if we reach the _ case of the pattern-match, it means that r is Fail and could be of any 'b result type, but what the compiler sees is that r is of type 'a result since it’s the input, and so 'a == 'b.