F# 记录:危险,仅用于有限用途,还是经常使用的功能?
所以我开始记录我的 F# 之旅,起初它们看起来相当危险。乍一看,这似乎很聪明:
type Card = { Name : string;
Phone : string;
Ok : bool }
let cardA = { Name = "Alf" ; Phone = "(206) 555-0157" ; Ok = false }
cardA 是 patten 的想法与 Card 相匹配。更不用说这里简化的模式匹配:
let withTrueOk =
list
|> Seq.filter
(function
| { Ok = true} -> true
| _ -> false
)
问题是:
type Card = { Name : string;
Phone : string;
Ok : bool }
type CardTwo = { Name : string;
Phone : string;
Ok : bool }
let cardA = { Name = "Alf" ; Phone = "(206) 555-0157" ; Ok = false }
cardA 现在是 CardTwo 类型,我猜测这与 F# 按顺序运行所有内容有关。
现在这可能是一种不可能的情况,因为可能永远不可能有两种类型的相同签名,但这是有可能的。
录制的内容是否用途有限,还是我只是想太多了?
So have gotten to record in my F# journey and at first they seem rather dangerous. At first this seemed clever:
type Card = { Name : string;
Phone : string;
Ok : bool }
let cardA = { Name = "Alf" ; Phone = "(206) 555-0157" ; Ok = false }
The idea that the cardA is patten matched with Card. Not to mention the simplified pattern matching here:
let withTrueOk =
list
|> Seq.filter
(function
| { Ok = true} -> true
| _ -> false
)
Problem is:
type Card = { Name : string;
Phone : string;
Ok : bool }
type CardTwo = { Name : string;
Phone : string;
Ok : bool }
let cardA = { Name = "Alf" ; Phone = "(206) 555-0157" ; Ok = false }
cardA is now of CardTwo type which I am guessing has to do with F# running everything in order.
Now this might be an impossible situation since there may never be a chance of the same signature taking on two type, but it is a possibility.
Is recording something that has only limited use or am I just over thinking this one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它们并不危险,而且用途不仅有限。
我认为两种类型的成员相同的情况非常罕见。但如果您确实遇到这种情况,您可以限定要使用的记录类型:
记录对于创建(大部分)不可变数据结构非常有用。事实上,您可以轻松创建仅更改某些字段的副本,这一点也很棒:
They are not dangerous and they are not only for limited use.
I think it's very rare that you would have two types with the same members. But if you do encounter that situation, you can qualify the record type you want to use:
Records are very useful for creating (mostly) immutable data structures. And the fact that you can easily create a copy with just some fields changed is great too:
我同意,将字段记录为封闭模块/命名空间的成员,乍一看对于更传统的面向对象语言来说似乎很奇怪。但 F# 在这里提供了相当大的灵活性。我认为您会发现只有人为的情况才会导致问题,例如两个
第一种情况永远不应该发生。后者可以通过具有记录A字段的记录B来解决。
只需要一个字段不同即可使两者区分开来。除此之外,定义可以相同。
模式匹配也非常灵活,因为您只需要匹配足够的字段即可将其与其他类型区分开来。
顺便说一句,您的场景可以通过类型注释轻松修复:
I agree, record fields as members of the enclosing module/namespace seems odd at first coming from more traditional OO languages. But F# provides a fair amount of flexibility here. I think you'll find only contrived circumstances cause problems, such as two records that
The first case should never happen. The latter could be solved by record B having a field of record A.
You only need one field to be different for the two to be distinguishable. Other than that, the definitions can be the same.
Pattern matching is also quite flexible as you only need to match on enough fields to distinguish it from other types.
Incidentally, your scenario is easily fixed with a type annotation:
为了让您了解 F# 提供的功能,我只想提一下,OCaml 中没有完全限定的记录访问器。因此,为了区分具有相同字段的记录类型,您必须将它们放入子模块中并使用模块前缀引用它们。
所以你在 F# 中的情况要好得多。类似记录类型之间的任何歧义都可以使用记录访问器快速解决:
此外,F# 记录根本不受限制。它提供了许多开箱即用的好功能,包括模式匹配、默认不变性、结构相等性等。
In order that you appreciate what F# provides, I just want to mention that there is no fully qualified accessor for records in OCaml. Therefore, to distinguish between record types with the same fields, you have to put them into submodules and reference them using module prefixes.
So your situation in F# is much better. Any ambiguity between similar record types could be resolved quickly using record accessor:
Moreover, F# record is not limited at all. It provides a lot of nice features out-of-the-box including pattern matching, default immutability, structural equality, etc.