管道操作员为什么工作? [英] Why does the pipe operator work?

查看:89
本文介绍了管道操作员为什么工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果管道操作符是这样创建的:

If the pipe operator is created like this:

let (|>) f g = g f

并以此方式使用:

let result = [2;4;6] |> List.map (fun x -> x * x * x)

然后似乎要做的就是获取List.Map并将其放在后面(有趣x-> x * x * x) 并没有改变[2; 4; 6]

Then what it seems to do is take List.Map and puts it behind (fun x -> x * x * x) And doesn't change anything about the position of [2;4;6]

所以现在看起来像这样:

So now it looks like this:

let result2 = [2;4;6] (fun x -> x * x * x) List.map

但是这不起作用.

我现在是第一次学习f#.这使我在阅读有关f#的书时感到困扰.所以我以后可能会知道我所缺少的东西,但是我还是决定去问.

I am just learning f# for the first time now. And this bothered me while reading a book about f#. So I might learn what I'm missing later but I decided to ask anyway.

很明显,我缺少一些重要的东西.由于我可以轻松地重新创建管道运算符.但是我不知道为什么它起作用.了解更多信息后,我可能会很快感到尴尬.哦,好吧.

It is obvious though that I am missing something major. Since I can easily recreate the pipe operator. But I don't get why it works. I might embarrass myself very soon as I learn more. Oh well.

推荐答案

管道运算符只是用于链式方法调用的语法糖.这与C#中linq表达式的表达方式非常相似.

The pipe operator is simply syntactic sugar for chained method calls. It's very similar to how linq expressions are expressed in C#.

来自前进管算子 我喜欢这个人. Forward管道运算符的简单定义为:

Forward Pipe Operator I love this guy. The Forward pipe operator is simply defined as:

let (|>) x f = f x

并具有类型签名:

'a -> ('a -> 'b) -> 'b

这将转换为:给定一个通用类型'a,以及一个接受'a并返回'b的函数,然后返回该函数在输入中的应用.

Which translates to: given a generic type 'a, and a function which takes an 'a and returns a 'b, then return the application of the function on the input.

除了解释这一点之外,让我举一个可以在何处使用的示例:

Rather than explaining this, let me give you an example of where it can be used:

// Take a number, square it, then convert it to a string, then reverse that string
let square x         = x * x
let toStr (x : int)  = x.ToString()
let rev   (x : string) = new String(Array.rev (x.ToCharArray()))

// 512 -> 1024 -> "1024" -> "4201"
let result = rev (toStr (square 512))

代码非常简单,但是请注意语法看起来有多么繁琐.我们要做的只是获取一个计算的结果,并将其传递给下一个计算.我们可以通过引入一系列新变量来重写它:

The code is very straight forward, but notice just how unruly the syntax looks. All we want to do is take the result of one computation and pass that to the next computation. We could rewrite it by introducing a series of new variables:

let step1 = square 512
let step2 = toStr step1
let step3 = rev step2
let result = step3

但是现在您需要将所有这些临时变量保持直线. (|>)运算符的作用是获取一个值,并将其转发"给函数,从本质上讲,您可以在函数调用之前指定函数的参数.通过允许您将函数通过管道传递到一起,从而将一个函数的结果传递到下一个函数,从而极大地简化了F#代码.因此,使用同一示例,代码可以清楚地写为:

But now you need to keep all those temporary variables straight. What the (|>) operator does is take a value, and 'forward it' to a function, essentially allowing you to specify the parameter of a function before the function call. This dramatically simplifies F# code by allowing you to pipe functions together, where the result of one is passed into the next. So to use the same example the code can be written clearly as:

let result = 512 |> square |> toStr |> rev

修改:

在F#中,您实际上对方法调用所做的事情是获取一个函数,然后将其应用于随后的参数,因此在您的示例中,将List.map (fun x -> x * x * x)应用于[2;4;6].管道操作员所做的全部工作就是以相反的顺序获取参数,然后由应用程序将其反转.

In F# what you're really doing with a method call is taking a function and then applying it to the parameter that follows, so in your example it would be List.map (fun x -> x * x * x) is applied to [2;4;6]. All that the pipe operator does is take the parameters in reverse order and then do the application reversing them back.

功能:List.map (fun x -> x * x * x) 参数:[2;4;6]

标准F#调用语法:f g

Standard F# call syntax: f g

反向F#调用语法:g f

Reversed F# call syntax: g f

标准

let var = List.map (fun x -> x * x * x) [2;4;6]

反面:

let var = [2;4;6] |> List.map (fun x -> x * x * x)

这篇关于管道操作员为什么工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆