Polymorphic variants of OCaml in comparison with the sample

I am developing a small programming language using AST transformations. That is, starting from a virtual machine and slowly adding layers that help the programmer.

Since each layer knows how to convert its new types, I did something like this:

module AST0 = struct

  type t = [
    | `Halt
    | `In
    | `Out
    | `Add of (int * int * int)
    | `Sub of (int * int * int)
  ]

  let lower (ast : t list) = ast
end

module AST1 = struct
  type t = [
    AST0.t

    | `Inc of int
    | `Dec of int 
    | `Cmp of (int * int * int)
  ]

  let lower (ast : t list) =
    let lower_one = function
      | `Inc a -> [`Add (a, a, `Imm 1)]
      | `Dec a -> [`Sub (a, a, `Imm 1)]
      | `Cmp (a, b) -> [`Sub (13, a, b)]
      | (x : AST0.t) -> AST0.lower [x]      (* <--- problem line *)
    in
    List.concat @@ List.map lower_one ast
end

Sorry, I get an error message:

File "stackoverflow.ml", line 28, characters 8-20:
Error: This pattern matches values of type AST0.t
       but a pattern was expected which matches values of type
         [? `Cmp of 'a * 'b | `Dec of 'c | `Inc of 'd ]
       The first variant type does not allow tag(s) `Cmp, `Dec, `Inc

I thought, because the compiler is smart enough to notice that I did not process options for XY and Z in the case of an arbitrary correspondence, he could say that xto AST1.lowernever be one Cmpor Incor Dec. This does not seem to be the case.

Am I misunderstood a system like OCaml? Am I missing something? Is this a stupid approach?

+4
1

case. : AST0.t AST0.t. ; `Inc AST0.t.

OCaml , . #AST0.t . . https://caml.inria.fr/pub/docs/manual-ocaml/lablexamples.html#sec46:

  (* I fixed several other trivial typing problems *)
  let lower (ast : t list) =
    let lower_one = function
      | `Inc a -> [`Add (a, a, 1)]
      | `Dec a -> [`Sub (a, a, 1)]
      | `Cmp (a, b, c) -> [`Sub (13, a, b)]
      | #AST0.t as x -> AST0.lower [x]     (* <--- problem line *)
    in
    List.concat @@ List.map lower_one ast

#AST0.t as x (`Halt | `In | `Out | `And _ | `Sub _ as x), x -> [> AST1.t] [> AST0.t]. AST0.t.

+6

Source: https://habr.com/ru/post/1682352/


All Articles