【问题标题】:F# Higher-order property accessorsF# 高阶属性访问器
【发布时间】:2010-06-07 20:40:40
【问题描述】:

我刚刚将我的原型元组升级为记录。有朝一日,它可能会成为一堂真正的课。同时,我想翻译这样的代码:

type Example = int * int
let examples = [(1,2); (3,4); (5,6)]
let descs = Seq.map (fst >> sprintf "%d") examples

到这里:

type Example = {
  Field1 : int
  Field2 : int
  Description : string
}
let examples = [{Field1 = 1; Field2 = 2; Description = "foo"}
                {Field1 = 3; Field2 = 4; Description = "bar"}
                {Field1 = 5; Field2 = 6; Description = "baz"}]
let descs = Seq.map Description examples

问题是当我声明示例记录时,我希望得到一个函数Description : Example -> string,但我没有。我已经四处寻找并尝试了类的属性,但这也不起作用。我只是在文档中遗漏了一些东西,还是必须手动编写高阶访问器? (这就是我现在使用的解决方法。)

【问题讨论】:

    标签: f# properties record accessor higher-order-functions


    【解决方案1】:

    我同意在 F# 中使用某种方式将实例成员用作函数值会很好(无需显式构造 lambda 函数)。这实际上已经在 F# 社区中讨论过几次。这是一个相关链接:

    该讨论中的一些建议选项是:

    // This would turn '_' automatically into a lambda parameter
    // (this looks okay in simple cases, but doesn't probably scale well)
    examples |> Seq.map (_.Description)
    
    // You would specify instance member using special '#' symbol
    examples |> Seq.map (Example#Description)
    

    所以,这是 F# 团队意识到的事情,但我认为这是否真的是一个重要的特性以及支持它的最佳方式是什么,尚无定论。

    【讨论】:

    【解决方案2】:
    examples |> Seq.map (fun e -> e.Description)
    

    (声明一条记录不会创建任何关联的函数,但记录具有属性,所以像上面这样的小 lambda 可以很容易地投影出某些字段。)

    【讨论】:

    • 嗯..这就是我所说的解决方法。在调用点写高阶访问器很冗长,在记录声明之后写很容易忘记。
    • 好的(“高阶访问器”在这里是一个奇怪的标签;lambda 不是高阶的)。是的,如果有“fun x -> x”的简写语法就好了。因为这是一个常见的成语。
    • 是的,我想不出一个更好的名字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2015-07-12
    • 2014-06-29
    • 2021-08-28
    相关资源
    最近更新 更多