gpt4 book ai didi

F# 管道运算符混淆

转载 作者:行者123 更新时间:2023-12-01 23:12:18 24 4
gpt4 key购买 nike

我正在学习 F#,而 |>、>> 和 << 运算符的用例让我感到困惑。我知道所有 if 语句、函数等都像变量一样工作,但它们是如何工作的?

最佳答案

通常我们(社区)说管道运算符(operator) |>只是一种方法,在函数调用之前编写函数的最后一个参数。例如

f x y

可以写

y |> f x

但为了正确起见,这不是真的。它只是将下一个参数传递给函数。所以你甚至可以写。

y |> (x |> f)

所有这些以及所有其他类型的运算符都有效,因为在 F# 中所有函数都是 curried默认情况下。这意味着,只存在带有一个参数的函数。具有许多参数的函数,实现为一个函数返回另一个函数。

你也可以这样写

(f x) y

例如。函数f是一个接受 x 的函数作为参数并返回另一个函数。然后得到 y作为参数传递。

这个过程是由语言自动完成的。所以如果你写

let f x y z = x + y + z

它是一样的:

let f = fun x -> fun y -> fun z -> x + y + z

顺便说一句,与类似 LISP 的语言相比,类似 ML 的语言中的括号不强制执行的原因。否则你需要写:

(((f 1) 2) 3)

执行函数f具有三个参数。

管道运算符本身只是另一个函数,它被定义为

let (|>) x f = f x

它需要一个值 x作为它的第一个参数。还有一个函数 f作为它的第二个参数。因为运算符是一个书面的“中缀”(这意味着在两个操作数之间)而不是“前缀”(在参数之前,正常方式),这意味着它给运算符的左参数是第一个参数。

在我看来,|>大多数 F# 人使用太多。如果您有一个接一个的操作链,那么使用管道是有意义的。通常,例如,如果您有多个列表操作。

比方说,您想要对列表中的所有数字进行平方,然后仅过滤偶数。没有管道你会写。

List.filter isEven (List.map square [1..10])

这里是 List.filter 的第二个参数是 List.map 返回的列表.也可以写成

List.map square [1..10]
|> List.filter isEven

管道是函数应用程序,这意味着您将执行/运行一个函数,因此它会计算并返回一个值作为其结果。

在上面的例子中List.map首先执行,结果传递给List.filter .有管道和没有管道都是如此。但有时,您想创建另一个函数,而不是执行/运行一个函数。假设您想从上面创建一个函数。您可以编写的两个版本是

let evenSquares xs = List.filter isEven (List.map square xs)
let evenSquares xs = List.map square xs |> List.filter isEven

你也可以把它写成函数组合。

let evenSquares = List.filter isEven << List.map square
let evenSquares = List.map square >> List.filter isEven

<<运算符类似于“正常”方式的函数组合,您将如何编写带括号的函数。和 >>是“向后”的组合,它是如何用 |> 写的.

F#的文档是反着写的,什么是向后和向前。但我认为 F# 语言的创造者是错误的。

函数组合运算符定义为:

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

如您所见,运算符在技术上具有三个参数。但请记住柯里化(Currying)。当你写 f << g ,那么结果是另一个函数,它需要最后一个参数 x .传递比需要的更少的参数通常也称为 Partial Application .

函数组合在 F# 中较少使用,因为如果函数参数是通用的,编译器有时会出现类型推断问题。

从理论上讲,您可以在不定义变量的情况下编写程序,只需通过函数组合即可。这也被命名为 Point-Free style .

我不推荐它,它通常会使代码更难阅读和/或理解。但如果你想将一个函数传递给另一个函数,有时会使用它 Higher-Order function .这意味着,一个函数将另一个函数作为参数。喜欢List.map , List.filter等等。

关于F# 管道运算符混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69659624/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com