Search code examples
f#pipeline

Piping another parameter into the line in F#


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 define
let 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?


Solution

  • 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