Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml 何时使用管道|>;反对论据_Ocaml_Conventions_Reason - Fatal编程技术网

Ocaml 何时使用管道|>;反对论据

Ocaml 何时使用管道|>;反对论据,ocaml,conventions,reason,Ocaml,Conventions,Reason,在Reason(和OCaml)中,有一种使用|>运算符传递参数的非传统方式。什么时候应该使用公约?我现在到处都在使用它,因为我觉得它很新奇。使用|>(前向管道)有助于显示执行顺序 例如,如果要执行函数f,则g如下: g(f(x)) (((wackymath a) b) c) 通过以下方式更容易查看执行顺序(例如,f,然后是g): x |> f |> g 像OCaml或F#这样的编程语言被大量用于将数据从一种形式转换为另一种形式,因此|>可以通过这种方式显示数据是如何被转换的 l

在Reason(和OCaml)中,有一种使用
|>
运算符传递参数的非传统方式。什么时候应该使用公约?我现在到处都在使用它,因为我觉得它很新奇。

使用
|>
(前向管道)有助于显示执行顺序

例如,如果要执行函数
f
,则
g
如下:

g(f(x))
(((wackymath a) b) c)
通过以下方式更容易查看执行顺序(例如,
f
,然后是
g
):

x |> f |> g
OCaml
F#
这样的编程语言被大量用于将数据从一种形式转换为另一种形式,因此
|>
可以通过这种方式显示数据是如何被转换的

let sqr = x => x * x;

[1,2,3]
|> List.map (x => x + 1)
|> List.map (sqr);

反向应用程序运算符(
|>
)可以简单地定义为

let (|>) x f = f x
此中缀运算符获取值
x
和函数
f
,并将后者应用于第一个(
f x
)。一开始,这似乎不是很有用,但正确使用该运算符时,它的功能非常强大,因为Ocaml中的函数非常有用

例如,假设我们有一个函数
wackymath:int->int->int->int->int

let wackymath a b c = a + b - c
wackymath
的类型是
int->int->int->int->int
。这是因为在函数领域(特别是lambda演算),任何函数一次只应用于一个参数。因此,借助括号,
wackymath
的应用顺序如下:

g(f(x))
(((wackymath a) b) c)
参数替换可以使这一点更清楚

let f1 = wackymath 10;; (* 10 + b - c *)
let f2 = f1 19;;        (* 10 + 19 - c *)  
f2 4;;                  (* 10 + 19 - 4 = 25 *)
这可以用
|>
操作符表示为:

4 |> (19 |> (10 |> wackymath));;
现在很清楚为什么它被称为反向应用程序操作符。之所以有括号,是因为
|>
是左关联的。说
|>
有助于避免括号并非在所有情况下都精确

通常,当您想要组合一系列顺序函数应用程序时,运算符非常有用

[1; 2; 3; 4; 5]
|> List.map (fun x -> x * 2)
|> List.filter (fun x -> x < 3)
|> fun l -> match l with
   | [] -> 0
   | l' -> l' |> List.fold_left ~init:0 ~f:(fun a b -> a + b)
;;
[1;2;3;4;5]
|>List.map(乐趣x->x*2)
|>List.filter(乐趣x->x<3)
|>有趣的l->与我匹配
| [] -> 0
|l'->l'|>List.fold_left~init:0~f:(乐趣a b->a+b)
;;

如果它类似于Clojure的线程宏
->
(将一个表达式的结果作为下一个表达式的第一个参数传递,并沿所有表达式继续传递),则当需要进行长链/管道调用以转换数据时,应使用它。我在任何地方都使用这样的宏,因为它们消除了嵌套调用并提高了可读性。@Carcigenicate换句话说,我应该一直使用它们,除非它确实会损害可读性?从Clojure的角度来看,是的。每当我必须通过>=2转换“线程化”参数时,我都会使用线程化宏,除非我有理由相信它可能会损害可读性,或者由于参数顺序不匹配而不可行。它们允许你以后更容易地向“管道”中添加零件,正如答案所指出的,这会导致更好的阅读顺序。在Clojure中,它是一个宏,因此甚至没有运行时成本。但我不确定它在OCaml中是如何工作的。什么时候不应该使用它?这取决于样式和代码可读性。我看不出
x |>f
f(x)
好多少,或者在
OCaml/f#
fx
,所以我永远不会那样使用它。