Polymorphism in OCaml - ad hoc,parametric, inclusion/subtyping

后端 未结 3 1981
鱼传尺愫
鱼传尺愫 2021-02-10 08:46

I am having a problem understanding the different types of polymorphism, specifically in regards to OCaml. I understand that polymorphism allows for multiple types in OCaml den

3条回答
  •  情深已故
    2021-02-10 09:42

    I actually don't think this kind of question is particularly suited to the strengths of Stack Overflow. There are entire books written about types. In fact, I'd recommend reading Types and Programming Languages by Pierce, which I found to be extremely enlightening and delightful.

    As a quick answer (based mostly on what I remember from Pierce :-), here's my take on these terms.

    parametric polymorphism refers to types with free variables in them, where the variables can be replaced by any type. The function List.length has such a type, as it can find the length of any list (no matter what the type of the elements).

    # List.length;;
    - : 'a list -> int = 
    

    One of the fantastic things about OCaml is that it not only supports types like this, it infers them. Given a function definition, OCaml infers the most general parametrically polymorphic type for the function.

    Subtyping is a relation between types. A type T is a subtype of the type U if all instances of T are also instances of U (but not necessarily vice versa). OCaml supports subtyping, that is, it allows a program to treat a value of type T as a value of its supertype U. However, the programmer has to ask for this explicitly.

    # type ab = [ `A | `B ];;
    type ab = [ `A | `B ]
    # type abc = [`A | `B | `C ];;
    type abc = [ `A | `B | `C ]
    # let x : ab = `A;;
    val x : ab = `A
    # let y : abc = x;;
    Error: This expression has type ab but an expression was expected
    of type abc. The first variant type does not allow tag(s) `C
    # let y : abc = (x :> abc);;
    val y : abc = `A
    

    In this example, type type ab is a subtype of type abc, and x has type ab. You can use x as a value with type abc, but you must explicitly convert using the :> type operator.

    Ad-hoc polymorphism refers to polymorphism that is defined by the programmer for particular cases, rather than being derived from fundamental principles. (Or at least that's what I mean by it, maybe other people use the term differently.) A possible example of this is an OO inheritance hierarchy, where the actual types of the object state need not be related in any way as long as the methods have the proper relations.

    The key observation about ad-hoc polymorphism (IMHO) is that it's up to the programmer to make it work. Hence, it doesn't always work. The other types of polymorphism here, being based on fundamental principles, actually can't fail to work. That's a comforting feeling when working with complex systems.

提交回复
热议问题