Search code examples
typesocamlrecords

ocaml type within a type


If I have a type in a module State

type state = {x: int; y: int}

and I have another type in module Game

type game = State.state

how can I access the record values in a object with type game?

For example if I have a game "g", g.x gives me an "Unbound record field label x" error.


Solution

  • The names of the fields are in the State module namespace. You can say g.State.x, or you can open the State module.

    let f g = g.State.x
    

    Or:

    open State
    
    let f g = g.x
    

    If you want the fields to appear in the Game module namespace, you can repeat them:

    type game = State.state = {x: int; y: int}
    

    You can also use the include facility to include the State module.

    For example, your Game module could say:

    include State
    type game = state
    

    In either of these cases, you can refer to Game.x:

    let f g = g.Game.x
    

    Or:

    open Game
    let f g = g.x
    

    There are also two notations for opening a module for just a single expression:

    let f g = Game.(g.x)
    

    Or:

    let f g = let open Game in g.x
    

    Edit: Here's a Unix command-line session that shows the first (simplest) solution:

    $ cat state.ml
    type state = { x: int; y : int }
    $ cat game.ml
    type game = State.state
    $ cat test.ml
    let f (g: Game.game) = g.State.x
    
    let () = Printf.printf "%d\n" (f { State.x = 3; y = 4})
    $ ocamlc -o test state.ml game.ml test.ml
    $ ./test
    3