【问题标题】:Is it possible to write tacit functions in F#是否可以在 F# 中编写默认函数
【发布时间】:2010-12-20 21:14:04
【问题描述】:

Tacit or point-free style programming 允许创建函数而不考虑其参数。这可以在 F# 中完成吗?

【问题讨论】:

    标签: f# functional-programming tacit-programming


    【解决方案1】:

    只是为了配合 Chuck 的回答和 Chris Smiths 的评论,你可以写

    let digits = string_of_int >> String.length
    digits 9000;; // 4
    [1; 10; 100] |> List.map digits;; // [1;2;3]
    

    当你将这些组合和管道运算符与高阶函数结合起来时,你可以非常简洁地完成复杂的事情:

    let prodSqrtAbs = Seq.map (abs>>sqrt) >> Seq.reduce (*)
    prodSqrtAbs [| -9.0; 4.0 |];;  // 6.0
    

    编辑:我刚刚读到 J 及其隐式 fork 运算符。这是非常强大的。您可以在 F# 中构建等效的高阶运算符,但不会隐式应用它们。因此,例如,首先定义lift(使用显式参数)

    let lift op a b x = op (a x) (b x)
    

    然后显式应用它

    let avg = lift (/) List.sum List.length
    

    在您链接到的维基百科页面上获得类似于 the J example 的内容。但它并不是很“默契”。

    【讨论】:

    • 嗨,加布里埃尔。我可以问个问题吗? FSharp 中没有“隐式 fork”运算符是否会迫使我只编写一个参数的默认函数(将参数打包到元组/列表等中);但从不允许我写二/三/四/..-argument 的默认函数?
    【解决方案2】:

    当然。您所需要的只是函数组合和柯里化,而这两者在 F# 中都是可能的。

    let compose f1 f2 = fun x -> f1 (f2 x);;
    let digits = compose String.length string_of_int;;
    digits 9000;; // 4
    

    【讨论】:

    • 我会反过来写 compose,这样它看起来就像 >> 运算符。
    • F# 具有以下操作符用于执行此类操作 >>、、。
    猜你喜欢
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多