与可区分联合相比,在 F# 中使用记录类型时更加详细

发布于 2024-12-01 10:02:54 字数 396 浏览 1 评论 0原文

let Method = { Name:string } //oversimplification

let method_parser =
  spaces >>. many1Satisfy isLetter .>> spaces
  |>> (fun name -> { Name=name })

如果我选择使用方法区分联合,事情会更简洁一些:

let method_parser =
  spaces >>. many1Satisfy isLetter .>> spaces
  |>> Method

我相信在 F# 中使用记录类型时没有办法避免这种冗长的情况。我说得对吗?

let Method = { Name:string } //oversimplification

let method_parser =
  spaces >>. many1Satisfy isLetter .>> spaces
  |>> (fun name -> { Name=name })

Had I chosen to use a Method discriminated union, instead, and things would be a bit more succinct:

let method_parser =
  spaces >>. many1Satisfy isLetter .>> spaces
  |>> Method

I believe there is no way to avoid this kind of verbosity when using record types in F#. Am I right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苦行僧 2024-12-08 10:02:54

记录与只有一个案例的受歧视联盟非常相似。在某些情况下,我也更喜欢联合,因为它更容易使用。然而,记录有两个主要优点:

  • 它们为字段命名,这在一定程度上导致了冗长,但使代码更加不言自明
    如果字段数量较少,可以使用元组或单例联合。

  • 它们允许您使用 { info with Name = "Tomas" } 语法来克隆记录
    如果您不需要这个,您可以使用标准 F# 类(具有更多 .NET 风格)

如果你想获得记录的好处,但仍然使用简单的语法来创建,那么你可以定义一个静态成员来构造你的记录:

type Info = 
  { Name : string 
    Count : int }
  static member Create(name:string, count:int) = 
    { Name = name; Count = count }

然后你可以写:

// Simple example using the above type:
let res = ("hello", 5) |> Info.Create

// I expect this would work for your type like this:
let method_parser = 
   spaces >>. many1Satisfy isLetter .>> spaces 
   |>> Method.Create

A record is very similar to a discriminated union with just a single case. In some cases, I would also prefer a union, because it is easier to use. However, records have two main advantages:

  • They give names to the fields, which partly causes the verbosity, but makes code more self-explanatory
    If you have small number of fields, you can use tuple or single-case union.

  • They allow you to use the { info with Name = "Tomas" } syntax for cloning records
    If you don't need this, you can use standard F# classes (which have more .NET feel)

If you want to get the benefits of records, but still use simple syntax for creating then, then you can define a static member for constructing your record:

type Info = 
  { Name : string 
    Count : int }
  static member Create(name:string, count:int) = 
    { Name = name; Count = count }

Then you can write:

// Simple example using the above type:
let res = ("hello", 5) |> Info.Create

// I expect this would work for your type like this:
let method_parser = 
   spaces >>. many1Satisfy isLetter .>> spaces 
   |>> Method.Create
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文