What is a principal type?

前端 未结 2 1272
执笔经年
执笔经年 2021-02-02 13:12

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

2条回答
  •  北荒
    北荒 (楼主)
    2021-02-02 13:52

    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!).

提交回复
热议问题