Sorry about the "what am I missing here" style of question here, but I'm just missing something here.
I was trying to understand how GADTs work in OCaml, I define the following (in utop
):
type value =
| Bool : bool -> value
| Int : int -> value
;;
type _ value =
| Bool : bool -> bool value
| Int : int -> int value
;;
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : 'a expr * 'a expr -> bool expr
| Eq : 'a expr * 'a expr -> bool expr
| Gt : 'a expr * 'a expr -> bool expr
;;
I defined an eval
function:
let rec eval : type a. a expr -> a = function
| Value (Int i) -> i
| Value (Bool b) -> b
| Lt (a, b) -> (eval a) < (eval b)
| Gt (a, b) -> (eval a) > (eval b)
| Eq (a, b) -> (eval a) = (eval b)
| If (c, a, b) -> if eval c then (eval a) else (eval b)
;;
but got an error:
Line 4, characters 15-23:
Error: This expression has type $Lt_'a but an expression was expected of type
int
What exactly does this mean?
Just to test further, I modified the expression GADT to be:
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : 'a expr * 'a expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
and then I see
Line 6, characters 15-23:
Error: This expression has type $Eq_'a but an expression was expected of type
int
When I finally modify it to be
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : int expr * int expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
it works fine.
Update (more context):
- Ocaml version:
4.08.1
- Libraries opened during this session:
Base
Update (solution):
- it turned out to be (as mentioned in the first line of the selected answer) because I had previously, within
utop
runopen Base ;;
- In a fresh session I'm able to enter the types initially mentioned and
eval
is happy with that.