Search code examples
ocamlalgebraic-data-types

How to concisely unwrap an algebraic data type in OCaml?


Is there a good way to concisely unwrap an algebraic data type in OCaml? For example, consider the following code that defines two different types of mathematical functions

type ftype =                                                         
    | Quadratic of {alpha : float; a : float array; aa : float array}
    | General of {eval : float array->float}
type myfn = {                                                                   
    nvar : int;
    typ : ftype}  
let f = {                                                                       
    nvar = 2;                                                                   
    typ = General {eval = fun x-> x.(0) +. x.(1)}} 

For debugging purposes, it sometimes nice to just evaluate a function or check its values in the top level. However, if we want to evaluate f, we require a code that looks like

let x = [| 1.; 2. |]
let y = match f.typ with General(f) -> f.eval(x)

This is kind of ugly and a pain to type especially if the layering is several layers deep. I'd like to define some kind of syntax such as

let y = f.typ.General.eval(x)

And, yes, the code is not safe and this will not compile. That said, something close to this would be nice for debugging purposes, so that we don't have to write a lengthy piece of code to unwrap a value. Is there a good way to accomplish this?


Solution

  • If it is just for debugging purposes, you can always write:

    let { typ = General { eval; } ; } = f in
    let y = eval x in
    ...
    

    Of course, the compiler will print you a warning 8 (non-exhaustive pattern matching).

    I don't think you can do more concise, sum types are meant to be readable and safe. Not to be quick, sorry.