9

管道参数是否仅适用于接受一个参数的函数?如果我们看一下Chris Smiths 页面上的示例,


// Using the Pipe-Forward operator (|>)
let photosInMB_pipeforward =
    @"C:\Users\chrsmith\Pictures\"
    |> filesUnderFolder
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

其中他的 filesUnderFolder 函数只需要 rootFolder 参数,如果该函数需要两个参数怎么办,即
let filesUnderFolder size rootFolder

然后这不起作用:


// Using the Pipe-Forward operator (|>)
let size= 4
let photosInMB_pipeforward =
    @"C:\Users\chrsmith\Pictures\"
    |> filesUnderFolder size
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

由于我可以定义
let inline (>>) f g x y = g(f x y)
,我认为我应该能够将管道运算符与具有多个输入参数的函数一起使用,对吧?我错过了什么?

4

3 回答 3

16

混合管道运算符和咖喱参数时,请注意传递参数的顺序。

let size = 4
let photosInMB_pipeforward =
    size, @"C:\Users\chrsmith\Pictures\"
    ||> filesUnderFolder
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

把它想象成编译器在函数和它的参数周围加上括号,就像这样。

@"C:\Users\chrsmith\Pictures\" |> filesUnderFolder size
变成
@"C:\Users\chrsmith\Pictures\" |> (filesUnderFolder size)

(filesUnderFolder size) @"C:\Users\chrsmith\Pictures\"

乱序示例

let print2 x y = printfn "%A - %A" x y;;

(1, 2) ||> print2;;
1 - 2

1 |> print2 2;;
2 - 1

有三个论据

let print3 x y z = printfn "%A - %A - %A" x y z;;

(1, 2, 3) |||> print3;;
1 - 2 - 3

(2, 3) ||> print3 1;;
1 - 2 - 3

3 |> print3 1 2;;
1 - 2 - 3

定义

let inline (|>) x f = f x

let inline (||>) (x1,x2) f = f x1 x2

let inline (|||>) (x1,x2,x3) f = f x1 x2 x3
于 2010-02-25T01:44:43.833 回答
11

您建议的示例应该可以正常工作,a la

let add x y = x + y

41
|> add 1
|> printfn "%d"

如果filesUnderFolder需要两个 curried args,并且您将其部分应用于一个 arg,则可以在管道中将其用于另一个。

(还要注意鲜为人知的管道运营商||>

(41,1)
||> add
|> printfn "%d"

它需要一个 2 元组并将它们按顺序输入到后面的内容中。)

于 2010-02-25T00:42:02.733 回答
4

这可能是不好的风格(?),但您可以“从右侧”向管道添加其他参数

let h x y z = x + y - z

let sub x y = x - y

let sqr x = x * x

3 |> h <| 2 <| 7
  |> sub <| 23
  |> sqr

// is the same as
sqr (sub (h 3 2 7) 23)
于 2015-11-19T14:38:45.993 回答