F# 函数组合,其中第一个函数的 arity 为 >1



我有两个函数fg:

let f (x:float) (y:float) = 
    x * y
let g (x:float) = 
    x * 2.0

我想组成(>>)他们得到一个新的功能,执行f,然后g的结果。

解决方案应该表现为:

let h x y = 
    (f x y) |> g

这行不通:

// Does not compile
let h = 
    f >> g

>>应该如何使用?

我认为你想达到这个目标:

let fog x  =  f x >> g 

你不能按照这个顺序直接组合它们f >> g,这是有意义的,因为f需要两个参数,所以执行f x将导致部分应用函数,但是g需要一个值,而不是一个函数。

以另一种方式组合可以工作,并且在您的特定示例中您甚至可以得到相同的结果,因为您使用的是交换函数。你可以做g >> f,你得到一个组成,导致部分应用的函数,因为g期望一个值,所以通过将一个值应用到g,你得到另一个值(不是一个函数),f期望两个值,然后你会得到一个部分应用的函数。

以无点风格编写,即定义没有显式参数的函数,当隐式参数多于一个时可能会变得很难看。

总是可以用正确的操作符组合来完成的。但结果将是令人失望的,你将失去无点样式的主要好处——简单和易读。

为了好玩和学习,我们试一试。让我们从显式的(又名。"pointful")风格,并从那里开始工作。

(注意:我们将把组合操作符重新排列成它们的显式形式(>>) (a) (b),而不是更常见的a >> b。这将创建一堆括号,但它将使事情更容易理解,而不必担心有时不直观的操作符优先规则。

let h x y =  f x y |> g
let h x = f x >> g
// everybody puts on their parentheses!
let h x = (>>) (f x) (g)
// swap order
let h x = (<<) (g) (f x)
// let's put another pair of parentheses around the partially applied function
let h x = ((<<) g) (f x)

我们到了!看,现在h x以我们想要的形状表示 -"将x传递给f,然后将结果传递给另一个函数"。

该函数恰好是((<<) g),该函数接受float -> float作为参数,并返回与g的组合。

(g出现在第二个的组合,这很重要,即使在特定的示例中使用它也没有区别。)

我们的float -> float参数当然是(f x),即f的部分应用。

所以,下面的代码可以编译:

let h x = x |> f |> ((<<) g)

现在可以很清楚地简化为

let h = f >> ((<<) g)

当你已经知道它的意思时,并不是所有的看起来都很糟糕。但是任何有理智的人都更愿意写和读 let h x y = f x y |> g

相关内容

  • 没有找到相关文章

最新更新