Variants or Polymorphic variants?

前端 未结 3 660
萌比男神i
萌比男神i 2020-12-23 11:25

I noticed that, among OCaml programmers I know, some of them always use polymorphic variants (variants that are not declared, prefixed with a backquote), while othe

3条回答
  •  我在风中等你
    2020-12-23 12:12

    It's not true that polymorphic variants are always less efficient. Using Martin's example:

    type base = [`String of string | `Int of int]
    type t1 = [base | `Bool of bool | `List of t1 list]
    type t2 = [base | `Other]
    
    let simplify (x:t1):t2 = match x with
    | #base as b -> b
    | `Bool _ | `List _ -> `Other
    

    To do this with standard variants requires two distinct types and a complete recoding, with polymorphic variants the base case is physically invariant. This feature really comes into its own when using open recursion for term rewriting:

    type leaf = [`String of string | `Int of int]
    type 'b base = [leaf | `List of 'b list]
    type t1 = [t1 base | `Bool of bool ]
    type t2 = [t2 base | `Other]
    
    let rec simplify (x:t1):t2 = match x with
    | #leaf as x -> x
    | `List t -> `List (List.map simplify t)
    | `Bool _ -> `Other
    

    and the advantages are even greater when the rewriting functions are also factored with open recursion.

    Unfortunately Ocaml's Hindley-Milner type inference is not strong enough to do this kind of thing without explicit typing, which requires careful factorisation of the types, which in turn makes proto-typing difficult. Additionally, explicit coercions are sometimes required.

    The big downside of this technique is that for terms with multiple parameters, one soon ends up with a rather confusing combinatorial explosion of types, and in the end it is easier to give up on static enforcement and use a kitchen sink type with wildcards and exceptions (i.e. dynamic typing).

提交回复
热议问题