OCaml gives function `A -> 1 | _ -> 0
the type [> `A] -> int
, but why isn't that [> ] -> int
?
This is my reasoning:
function `B -> 0
has type[<`B] -> int
. Adding a`A -> 0
branch to make itfunction `A -> 1 | `B -> 0
loosens that to[<`A|`B] -> int
. The function becomes more permissive in the type of argument it can accept. This makes sense.function _ -> 0
has type'a -> int
. This type is unifiable with[> ] -> int
, and[> ]
is an already open type (very permissive). Adding the`A -> 0
branch to make itfunction `A -> 1 | _ -> 0
restricts the type to[>`A] -> int
. That doesn't make sense to me. Indeed, adding still another branch`C -> 1
will make it[>`A|`C] -> int
, further restricting the type. Why?
Note: I am not looking for workarounds, I'd just like to to know the logic behind this behavior.
On a related note, function `A -> `A | x -> x
has type ([>`A] as 'a) -> 'a
, and while that is also a restrictive open type for the parameter, I can understand the reason. The type should unify with 'a -> 'a
, [>` ] -> 'b
, 'c -> [>`A]
; the only way to do it seems to be ([>`A] as 'a) -> 'a
.
Does it exist a similar reason for my first example?
(function `A -> 1 | _ -> 0) ((fun x -> (match x with `B -> ()); x) `B)
to fail to type-check. Might there be a deeper reason? I'll wait a little bit more before accepting your answer. – Kutzer