msdn页面记录Records (F#)详细信息record expressions
用于记录构建,record patterns
用于解构,后者没有将它们命名为。
这是一个使用两种技术进行算术运算的例子:
// Simple two-dimensional generic vector defintion
type 'a UV =
{ U : 'a; V : 'a }
static member inline (+) ({ U = au; V = av }, { U = bu; V = bv }) =
{ U = au + bu; V = av + bv }
这显得笨拙且不易阅读。对于解构,有点符号或函数作为替代。由于点符号运算符在规范(an expression’s type may be inferred from a record label
)的8.4.2 名称解析和记录字段标签部分中有特殊的分配,因此通常无需注释。像let u { U = u } = u
这样的访问器功能不会给我们任何优势。
对于构造,我认为可以将一个函数作为记录构造函数。甚至可能限制对原始构造函数的访问:
type 'a UV =
internal { U : 'a; V : 'a }
let uv u v = { U = u; V = v }
type 'a UV with
static member inline (+) (a, b) =
uv (a.U + b.U) (a.V + b.V)
这是一个惯用的事吗?如何在模块中打包这些函数并处理命名空间问题?
答案 0 :(得分:5)
简短回答:我认为目前这里没有一般性约定,所以最终将是个人决定。
总结一下您获得的免费以及F#中的记录:
构造:{ 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。
更新(以回应您的评论)
当然,他们可以在以后定义,它会改变什么?
这同样适用于New
构造函数,它可以在以后定义,但这实际上是一件好事。
您定义的访问器函数也可以在以后定义,实际上可以在以后定义任何第一类getter,setter或updater值。
无论如何,你的问题的答案是“不,没有约定”,其余的是个人决定,这将是我的决定,而且许多Haskellers正在努力为Haskell记录获得某种自动镜头。
为什么我决定这样走?因为在代码行方面,添加简单访问器功能的工作与添加get-Lens几乎相同,因此以相同的价格获得更多功能。
如果您对镜头讨论不满意,请告诉我,我可以将其删除并留下简短的答案,或者如果它混淆而不是澄清,我也可以删除整个答案。
或者我可能误解了你的问题,对我来说,你的问题是关于哪种约定通常用于为记录添加一流的构造函数,getter和setter值。
组合不是镜片的唯一优势,你可以做很多事情,继续阅读它们,它们提供了一个非常有趣的抽象,而且不仅限于记录。