The OCaml compiler has a \"-principal\" option and the term \"principal type\" is sometimes mentioned in the mailing list. What exactly does it mean? The definition in Wikiped
To build a little bit upon gasche's explanation, here's an example, stolen from OCaml's own testsuite, where principality, or lack thereof, appears. Disclaimer: this uses objects.
class c = object method id : 'a. 'a -> 'a = fun x -> x end;;
type u = c option;;
let just = function None -> failwith "just" | Some x -> x;;
let f x = let l = [Some x; (None : u)] in (just(List.hd l))#id;;
let g x =
let none = (fun y -> ignore [y;(None:u)]; y) None in
let x = List.hd [Some x; none] in (just x)#id;;
let h x =
let none = let y = None in ignore [y;(None:u)]; y in
let x = List.hd [Some x; none] in (just x)#id;;
When running this in a top-level session, you'll get:
# val f : c -> 'a -> 'a =
# val g : c -> 'a -> 'a =
# val h : < id : 'a; .. > -> 'a =
These functions perform the exact same thing but get assigned different types!
If you invoke OCaml with the -principal
option, the first two examples will trigger:
Warning 18: this use of a polymorphic method is not principal.
The interesting thing is that if you replace 'a
in the type of h
with 'a -> 'a
, you get the exact same type as f
and g
, since the type c
is just a type abbreviation for (i.e. expands to) < id: 'a -> 'a; .. >
.
What the compiler wants to tell the programmer here is that there are two suitable types for f
and g
, and that there is no criterion that would help OCaml decide which one is the "best" (and by "best", I mean "principal", of course!).