Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to forward pipe a value to the left side parameter of a function?

Tags:

f#

f#-3.0

For example,

let fn x y = printfn "%i %i" x y
1 |> fn 2 // this is the same as fn 2 1 instead of fn 1 2

How to make it fn 1 2?

This is just a simplified example for test. I have a complex function return a value and I want to forward pipe it to the left side (in stead of right side) of a function.

like image 985
ca9163d9 Avatar asked Sep 26 '13 05:09

ca9163d9


2 Answers

I assume that you have at least two pipes. Otherwise, fn 1 2 does the job; why should we make it more complicated?

For commutative functions (which satisfy f x y = f y x) such as (+), (*), etc. you can just use 1 |> fn 2.

For other functions, I can see a few alternatives:

  1. Use backward pipes

    arg1
    |> fn1
    |> fn2 <| arg2
    

    I tend to use this with care since operators' precedence might cause some subtle bugs.

  2. Use flip function

    let inline flip f x y = f y x
    
    Array.map2 (fun y d -> (y - d) ** 2.0) y d
    |> Array.sum
    |> flip (/) 2.0
    

    It's not pretty but it's clear that order of arguments in (/) is treated differently.

  3. Use anonymous functions with fun and function keywords
    This is handy if you need pattern matching in place.

    input
    |> createOption
    |> function None -> 0 | Some _ -> 1
    

IMO, you don't have to pipe all the way. Create one more let binding, then your intention is clear and you can avoid bugs due to unusual styles.

let sum =
   Array.map2 (fun y d -> (y - d) ** 2.0) y d
   |> Array.sum
 sum / 2.0    
like image 94
pad Avatar answered Sep 29 '22 10:09

pad


Here is a solution that looks pretty. I don't know if it is too practical though

1 |> fn <| 2
like image 45
John Palmer Avatar answered Sep 29 '22 10:09

John Palmer