问题
Is piping parameter into line is working only for functions that accept one parameter? If we look at the example at Chris Smiths' page,
// Using the Pipe-Forward operator (|>)
let photosInMB_pipeforward =
@"C:\Users\chrsmith\Pictures\"
|> filesUnderFolder
|> Seq.map fileInfo
|> Seq.map fileSize
|> Seq.fold (+) 0L
|> bytesToMB
where his filesUnderFolder function was expecting only rootFolder parameter,
what if the function was expecting two parameters, i.e.let filesUnderFolder size rootFolder
Then this does not work:
// 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
Since I can definelet inline (>>) f g x y = g(f x y)
I think I should be able to use pipeline operator with functions having multiple input parameters, right? What am I missing?
回答1:
When mixing pipeline operators and curried arguments be aware of the order you pass arguments with.
let size = 4
let photosInMB_pipeforward =
size, @"C:\Users\chrsmith\Pictures\"
||> filesUnderFolder
|> Seq.map fileInfo
|> Seq.map fileSize
|> Seq.fold (+) 0L
|> bytesToMB
Think about it as if the compiler is putting parentheses around the function and its parameters like this.
@"C:\Users\chrsmith\Pictures\" |> filesUnderFolder size
becomes@"C:\Users\chrsmith\Pictures\" |> (filesUnderFolder size)
or(filesUnderFolder size) @"C:\Users\chrsmith\Pictures\"
Out of order example
let print2 x y = printfn "%A - %A" x y;;
(1, 2) ||> print2;;
1 - 2
1 |> print2 2;;
2 - 1
With three arguments
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
Definitions
let inline (|>) x f = f x
let inline (||>) (x1,x2) f = f x1 x2
let inline (|||>) (x1,x2,x3) f = f x1 x2 x3
回答2:
The example you suggested should work fine, a la
let add x y = x + y
41
|> add 1
|> printfn "%d"
If filesUnderFolder
takes two curried args, and you partially apply it to one arg, you can use it in the pipeline for the other.
(Note also the lesser known pipeline operator ||>
(41,1)
||> add
|> printfn "%d"
which takes a 2-tuple and feed them sequentially into what follows.)
回答3:
It may be bad style (?), but you can add additional parameters to the pipeline 'from the right side'
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)
来源:https://stackoverflow.com/questions/2330779/piping-another-parameter-into-the-line-in-f