f# - 是否有将一系列管道转换为功能组合的分步过程?

标签 f# functional-programming

是否有将多个管道转换为功能组合的分步过程?

旁注:
我什至在正确的上下文中使用了术语“功能组合”吗?

我有以下代码:

let purchase qty inventory =
    buyFrom inventory qty |> fromInventory
                          |> reduceBy qty

我想重构此代码以支持功能组合。

所以我想我可以这样做:
let purchase qty inventory =
    buyFrom inventory >> fromInventory >> reduceBy qty

此代码编译。但是,在尝试在调试器中调用购买函数时,我似乎缺少一个参数。

这是我对该功能的测试:
[<Test>]
let ``buy last product``() =
    [SomeProduct] |> purchase 1
                  |> should equal []

注意:

我仍在为 FP 基础而苦苦挣扎,并且仍然不了解将管道工作流转换为功能组合的过程。

我想我明白功能组合依赖于部分应用程序,我想我现在已经掌握了。因此,我有理由相信我的重构函数缺少一个参数。

关于我可以用来更好地进行功能组合的工作流程的任何指导?

附录:
type Product =
    | SomeProduct

type TransactionResult = { Price:decimal; Inventory:Product list }

(* Functions *)

let priceOf qty product =
    match product with
    | SomeProduct -> match qty with
                     | 3 -> decimal (qty - 1) * 1.99m
                     | _ -> decimal (qty) * 1.99m

let rec reduceBy count list =
    match list with
    | first::remaining when count = 1         -> remaining
    | first::second::remaining when count > 1 -> second::remaining |> reduceBy (count - 1)
    | remaining when count = 0                -> remaining
    | _ -> []

let buyFrom inventory qty =
    { Price=priceOf qty (List.head inventory); Inventory=inventory }

let fromInventory transactionResult =
    transactionResult.Inventory

最佳答案

直接翻译为组合形式将是:

使用“转发”函数组合:

let purchase qty inventory = (buyFrom inventory >> fromInventory >> reduceBy qty) qty

使用“向后”函数组合(就个人而言,我不确定我喜欢术语“向后”,因为这是该术语传统数学意义上的函数组合,即 f << g = f ∘ g ):
let purchase' qty inventory = reduceBy qty << fromInventory << buyFrom inventory <| qty

从上面的示例中您或许可以看出,当它让您完全跳过最后一个参数时,它确实最有值(value)。在这个例子中,你不能这样做,因为你依赖于 qty两次所以我建议你在这里坚持使用管道。

一般来说,如果你有一个函数 f(x)和一个函数 g(x)你可以写一个组合函数h(x) = (f ∘ g)(x)通过以下方式:
let h x = f (g (x))
let h x = x |> g |> f
let h x = f << g <| x
let h x = (g >> f) x

后两种情况,使用函数组合,可以省略x完全。
let h = f << g
let h = g >> f

关于f# - 是否有将一系列管道转换为功能组合的分步过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38504899/

相关文章:

functional-programming - CL中优化速度声明的作用是什么?

f# - 如何打开和使用库: "Fsharp.Charting && Fsharp.Charts" in Fsharp?

f# - 如何为 .NET Compact Framework 构建 FParsec?

arrays - Haskell map/sortBy/findIndex 等用于数组而不是列表

ruby - 在 Ruby 中乱序柯里化(Currying)

eclipse - 哪种函数式编程语言在 Eclipse 中提供最好的支持?

haskell - 函数式编程语言中的调用站点代码替换

f# - WebSharper 3.4 与有效的 HelloWorld 示例?

f# - 格式化乘法表 f# 输出

c# - 是否有 Hilbert-Huang 变换的 .Net(首选 F# 或 C#)实现?