Explicit polymorphic type in record

2020-07-27 16:35发布

问题:

In OCaml, it is possible to define explicit polymorphic type in a record

type foo = { f : 'a. unit -> 'a };;

It seems we can assign only general values to f like

{ f = fun () -> failwith ""; }

or

{ f = fun () -> exit 1; }

How to use this language feature in real world? Is there any good practical example?

回答1:

This isn't really connected with records. If you declare any function to have type 'a. unit -> 'a (takes nothing and returns whatever the caller wanted) then you can only use it for functions that don't return.

Here's a slightly more useful example: a record containing a function for finding the length of lists (of any type).

# type foo = { f : 'a. 'a list -> int };;
type foo = { f : 'a. 'a list -> int; }

# let foo = { f = List.length };;
val foo : foo = {f = <fun>}
# foo.f [1;2;3];;
- : int = 3

It can be useful if you wanted to pass a function like List.length as an argument to another function, and have it use it on multiple types:

Say we want to pass List.length to test. We can't do it directly:

# let test fn = fn [1;2;3] + fn ["a";"b";"c"];;
Error: This expression has type string but an expression was expected of type
         int

But we can use a record:

# let test foo = foo.f [1;2;3] + foo.f ["a";"b";"c"];;
val test : foo -> int = <fun>

# test foo;;
- : int = 6


标签: ocaml