2

我有两个功能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

应该如何>>使用?

4

2 回答 2

4

我认为你想实现这一点:

let fog x  =  f x >> g 

您不能直接f >> g按该顺序组合它们,这是有道理的,因为 f 需要两个参数,所以这样做f x会导致部分应用函数,但g需要一个值,而不是函数。

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

于 2015-10-12T16:45:01.583 回答
2

当隐式参数不止一个时,以无点风格编写,即定义没有显式参数的函数会变得很丑陋。

使用正确的运算符组合始终可以完成。但结果会令人失望,您将失去无点样式的主要好处——简单易读。

为了乐趣和学习,我们会试一试。让我们从显式(又名“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表示- “传递给,然后将结果传递给另一个函数”。xf

该函数恰好是((<<) g),该函数将 afloat -> 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

于 2015-10-12T19:06:21.660 回答