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?
A pipe function takes an n sequence of operations; in which each operation takes an argument; process it; and gives the processed output as an input for the next operation in the sequence. The result of a pipe function is a function that is a bundled up version of the sequence of operations.
What does the pipe do? The pipe operator, written as %>% , has been a longstanding feature of the magrittr package for R. It takes the output of one function and passes it into another function as an argument. This allows us to link a sequence of analysis steps.
Pipes are an extremely useful tool from the magrittr package 1 that allow you to express a sequence of multiple operations. They can greatly simplify your code and make your operations more intuitive. However they are not the only way to write your code and combine multiple operations.
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
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.)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With