Suppose that I have the following record:
type t = {a:int}
In order to select the values of field a
from a list I do the following:
let x = [{a=1};{a=2}]
let y = List.map (fun t -> t.a) x
This is a bit "unclean" to me. As a comparison, In Haskell I would do the following:
data T = T { a :: Int}
x = [T {a = 1}, T {a = 2}]
y = map a x
Is there a way to write something similar in Ocaml (maybe using external libraries)? If not possible 开发者_运维知识库can someone explain why this limitation?
If you use Jane Street's fieldslib library, available with core, then you can write:
type t = { a:int; b:int } with fields
and that gives you a
and b
as selector functions of type t -> int
It also gives you a submodule called Fields
of so-called first-class fields, which include the selector, the mutator, and, critically for some applications, the string name of the field. This is very useful for generating good error messages in validations functions, for example.
You also get some higher-order functions on the entire record, most usefully a fold over the record.
Unlike Standard ML, Ocaml doesn't have first-class selectors for records.(source)
As for why it cannot be done, that's simply a design choice that was made.
Haskell implicitly creates selector functions for field names. OCaml doesn't do this. You could just manually define them whenever you create record types, and it would be equivalent to what the Haskell code does.
type t = {a:int, b:int}
let a x = x.a
let b x = x.b
精彩评论