Matching on a constructor of a GADT may introduce a typing equation. In your example, matching on `A` introduces the equation `a = unit`.
For this reason, the status of or-patterns (p1 | p2) containing GADT constructors is delicate: to type-check them we have to decide which equations from both sides are preserved in the result, computing a sort of intersection.

Released versions of OCaml avoid this difficulty by not supporting GADTs in or-patterns at all; you have to expand the pattern into two branches, as you did in your function `f` above.

In the current trunk, a change from Thomas Réfis and Leo White has been merged that allows GADTs in or-patterns, but discards the equations. Your specific example (the function `g`) is now accepted, and will be typeable in 4.08. Other examples, where you need to use an equation (provided by both sides of the or-patterns) in the body of the clause, will still be rejected.


On Thu, Jan 17, 2019 at 10:46 AM Christopher Zimmermann <christopher@gmerlin.de> wrote:
Hi,

why does the f type correctly while g fails to type?

Christopher

type 'a t =
  | A : unit t

let f =
  fun (type a) ~(p :a t option) () -> match p with
    | Some A -> ()
    | None -> ()

let g =
  fun (type a) ~(p :a t option) () -> match p with
    | Some A (* TYPING ERROR HERE *)
    | None -> ()

Error: This pattern matches values of type unit t
       but a pattern was expected which matches values of type a t
       Type unit is not compatible with type a


--
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
CB07 DA40 B0B6 571D 35E2  0DEF 87E2 92A7 13E5 DEE1