【问题标题】:F#: Apply a value as though it is a functionF#:应用一个值,就好像它是一个函数一样
【发布时间】:2019-10-19 06:31:25
【问题描述】:

是否可以在 F# 中像函数一样应用值?例如:

let record =
    {|
        Func = fun x -> x * x
        Message = "hello"
    |}
let message = record.Message   // unsweetened field access
let unsweet = record.Func 3    // unsweetened function application
let sweet = record 3           // sweetened function application

现在,当然,最后一行没有编译:

error FS0003: This value is not a function and cannot be applied.

是否有某种语法甜味剂可以让我按照我认为合适的方式“路由”功能应用程序,同时仍保留其正常的不加糖行为?我在想这样的魔法:

// magically apply a record as though it was a function
let () record arg =
    record.Func arg

(注意:我在这个例子中使用了一条记录,但我也会对一个类感到满意。)

【问题讨论】:

  • 我认为您正在寻找一个 隐式运算符,例如您可以在 C# 中定义的(并用于透明地调用由 FuncAction 实例定义的方法)。 F# 有意识地决定不使用它们,所以你正在寻找的东西是不可能的。
  • 其实可以创建一个类,继承FSharpFunc<a, b>,实现自己的Invoke();但即便如此,它也需要显式向上转换为 obj 并重新向下转换为 a -> b 才能像普通函数一样调用它。所以我认为不可能随心所欲地做到这一点。
  • 感谢两位 cmets。我认为你是对的。

标签: function functional-programming f#


【解决方案1】:

我能想到的最接近的事情是使用静态解析的类型参数来解析FSharpFunc 类型的特定属性的自定义运算符,然后使用提供的输入参数调用该函数。像这样的:

let record =
    {|
        Func = fun x -> x * x
        Message = "hello"
    |}

let inline (>.>) (r: ^a) v = 
    let f = (^a : (member Func: FSharpFunc< ^b, ^c>) r)    
    f v

record >.> 3 // val it : int = 9

【讨论】:

  • 好建议,谢谢。这会起作用,除了我希望混合普通和“魔术”功能应用程序(即柯里化):makeRecord "hello" 3 将创建一条记录,然后将其应用于值 3。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 2021-12-27
  • 2020-01-10
  • 1970-01-01
相关资源
最近更新 更多