Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml polymorphic variants: bind the same name in multiple match patterns

I'm not sure if the title explains it well, but here's a concrete example: I have a polymorphic variant for shapes, and a print_round function which can act on a subset of those variants (the round ones):

type round_shape = [
    | `oval of int * int
    | `circle of int
]

type shape = [
    | round_shape
    | `rectangle of int * int
]

let print_round : round_shape -> unit = function
    | `oval (width, height) -> failwith "todo"
    | `circle radius -> failwith "todo"

Now, this function compiles:

let print_shape : shape -> unit = function
    | `rectangle _ -> failwith "TODO"
    | `oval _ as round -> print_round round
    | `circle _ as round -> print_round round

But that seems repetitive - this is the code I want to write:

let print_shape = function
    | `rectangle -> failwith "TODO"
    | `oval _ as round | `circle _ as round -> print_round round

With that code, I get:

Error: Variable round must occur on both sides of this | pattern

Which I just don't understand. Clearly round does appear on both sides. How can I get this to work to bind round as a round_shape in that last branch, with minimal type casting?

like image 546
gfxmonk Avatar asked Mar 08 '26 10:03

gfxmonk


1 Answers

The syntax for patterns you need is

pattern_1 | pattern_2 ... | pattern_n as name

The pattern grammar can be found here. Taking that into account we get

let print_shape = function
    | `rectangle -> failwith "TODO"
    | `oval _ | `circle _ as round -> print_round round
like image 185
Anton Trunov Avatar answered Mar 10 '26 12:03

Anton Trunov