Короткий ответ: Я не думаю, что в настоящий момент существует общее соглашение, поэтому в конце концов это будет личное решение.
Чтобы подвести итог, что вы получаете бесплатно с записями в F # является:
Construct: { U = u; V = v }
(кронштейн нотации)
деконструкции: let u = record.u
(точка-обозначения) и let {U = u} = record
(образец соответствия)
Обновление: {record with U = u}
(скобка-нотация)
Но вы не получаете функции первого класса бесплатно, если хотите, вы можете запрограммировать их вручную.
Ниже то, что я бы лично использовать в качестве конвенции:
static member New
с кэрри аргументами для записи строительства.
Для обновления и деконструкции я бы использовал некоторую абстракцию Lenses.
Вот пример кода, который я бы добавить вручную:
// Somewhere as a top level definition or in a base library
type Lens<'T,'U> = {Get: 'T -> 'U; Set: 'U -> 'T -> 'T } with
member l.Update f a = l.Set (f (l.Get a)) a
type UV<'a> = {U : 'a; V : 'a } with
// add these static members to your records
static member New u v : UV<'a> = {U = u; V = v}
static member u = {Get = (fun (x: UV<'a>) -> x.U); Set = fun t x -> {x with U = t}}
static member v = {Get = (fun (x: UV<'a>) -> x.V); Set = fun t x -> {x with V = t}}
let uvRecord = UV.New 10 20
let u = UV.u.Get uvRecord
let uvRecord1 = UV.u.Set (u+1) uvRecord
let uvRecord2 = UV.u.Update ((+)1) uvRecord
Таким образом, я бы первые функции класса для строительства, деконструкции, но и для обновления плюс другие очень интересные Линзы свойства, как вы можете read in this post.
UPDATE (в ответ на ваши комментарии)
Конечно, они могут быть определены позже, что это меняет? То же самое относится к конструктору New
, его можно определить позже, но на самом деле это хорошо. Определяемые вами функции доступа также могут быть определены позже, и в любом случае может быть определено любое значение первоклассного коэффициента получения, настройки или обновления.
В любом случае, ответ на ваш вопрос: «нет, нет никаких соглашений», остальное это личное решение, которое было бы моим решением, а также многие Haskellers настаивают на получении каких-либо автоматических линз для записей Haskell.
Почему я решил пойти этим путем? Поскольку в терминах строк кода усилие добавления простой функции доступа почти такое же, как добавление get-Lens, поэтому по той же цене я получаю больше функциональности.
Если вы недовольны обсуждением объективов, пожалуйста, скажите мне, я могу удалить его и оставить короткий ответ, или я могу удалить весь ответ, если он запутан, а не уточняет.
Возможно, я неправильно понял ваш вопрос, для меня ваш вопрос касался того, какое соглашение обычно используется для добавления первоклассных конструкторов, значений getters и seters для записей.
Композиция не является единственным преимуществом объективов, вы можете делать много вещей, продолжать читать о них, они обеспечивают очень интересную абстракцию и не ограничиваются только записями.
В то время как объективы великолепны для композиции, я не совсем понимаю вас в преимуществах их реализации, когда они определяют структуру данных. Поскольку ваш [link] (http://bugsquash.blogspot.fr/2011/11/lenses-in-f.html) демонстрирует посредством методов расширения, , они также могут быть представлены ретроспективно. Мотивация для этого вопроса заключалась в стремлении избежать рефакторинга определений записей, а не лаконичности и удобочитаемости. Как линзы помогут мне в этом, если бы вы все равно могли набить их? – kaefer
@kaefer Я ответил вам в обновлении. – Gustavo