Ocaml: Как «легко» сопоставить список записей со списком record.field? - PullRequest
6 голосов
/ 14 мая 2011

Предположим, что у меня есть следующая запись:

type t = {a:int}

Чтобы выбрать значения поля a из списка, я делаю следующее:

let x = [{a=1};{a=2}]
let y = List.map (fun t -> t.a) x

Этонемного "нечист" для меня.Для сравнения, в Haskell я бы сделал следующее:

data T = T { a :: Int}  
x = [T {a = 1}, T {a = 2}]
y = map a x

Есть ли способ написать что-то похожее в Ocaml (возможно, с использованием внешних библиотек)?Если это невозможно, кто-нибудь может объяснить, почему это ограничение?

Ответы [ 3 ]

9 голосов
/ 15 мая 2011

Если вы используете библиотеку fieldslib Джейн Стрит, доступную с core, то вы можете написать:

type t = { a:int; b:int } with fields

и это дает вам a и b в качестве функций выбора типа t -> int

Он также предоставляет вам подмодуль под названием Fields из так называемых полей первого класса , которые включают селектор, мутатор и, что критично для некоторых приложений, строковое имя поля. Это очень полезно для создания хороших сообщений об ошибках в функциях проверки, например.

Вы также получаете некоторые функции более высокого порядка для всей записи, наиболее полезно сгиб по записи.

6 голосов
/ 14 мая 2011

В отличие от стандартного ML, в Ocaml нет первоклассных селекторов для записей. ( источник )

Что касается того, почему этого нельзя сделать, это простовыбор дизайна, который был сделан.

3 голосов
/ 17 мая 2011

Haskell неявно создает функции селектора для имен полей. OCaml не делает этого. Вы можете просто определить их вручную при создании типов записей, и это будет эквивалентно тому, что делает код на Haskell.

type t = {a:int, b:int}
let a x = x.a
let b x = x.b
...