9
votes

In Scheme, I can write a function:

(define (eat-line line)
  eat-line)

Which I could use in a loop like:

(define (loop op)
  (let ((line (read-line))
    (loop (op line))))

In OCaml I tried to define a function:

let rec eat_line line = eat_line

But I got the error:

Error: This expression has type 'a -> 'b
   but an expression was expected of type 'b
   The type variable 'b occurs inside 'a -> 'b

Is it possible to define such a function in OCaml, or is it prevented by the type system? If so, why?

1

1 Answers

12
votes

You can define the function if you specify -rectypes when you run the interpreter or compiler:

$ ocaml -rectypes
        OCaml version 4.01.0

# let rec eat_line line = eat_line;;
val eat_line : 'b -> 'a as 'a = <fun>

# eat_line "yes" "indeed";;
- : string -> 'a as 'a = <fun>
# eat_line 3 5 7;;
- : int -> 'a as 'a = <fun>

Types like this (recursive or cyclic types) are not allowed by default because they are very often the result of coding errors.