2

I'm looking for a way to do point-free style division. Point free style works great with most mathematical operators where the order of the arguments doesn't matter as in the case of multiplication, subtraction or addition.

But the problem is with division where I want to do div(x, y) but the order becomes div(y, x). As in this example:

let aList = [2;4;6;8]
let mut = aList |> List.map ((/)2)

The partially applied function becomes (fun x -> 2 / x). Which will yield [1; 0; 0; 0] while I would like it to be (fun x -> x / 2) -> [1; 2; 3; 4].

Is there any easy way to do this in a point free style?

Overly Excessive
  • 2,095
  • 16
  • 31
  • 6
    If you're asking out of curiosity, than that's fine :-), but otherwise, please don't do this. Figuring out what `swap (/) 2` means is much harder than understanding `fun x -> x/2` and you're saving exactly 2 characters. – Tomas Petricek Dec 15 '14 at 12:24
  • @TomasPetricek You're right, there's a point where doing this will just make the code more obscure and less readable. The question was mostly out of curiosity. – Overly Excessive Dec 15 '14 at 14:02
  • Makes sense :-). It's amazing how flexible F# is and it's great to try that, which is why http://twitter.com/fsibot is so much fun! In practice, I like the fact that `swap` etc. are not included in the core libraries - it makes you think twice about this :-) – Tomas Petricek Dec 15 '14 at 14:47
  • The order of the arguments doesn't matter for subtraction? Are you sure? :) – Grundoon Dec 16 '14 at 12:28
  • You're right, it does matter, my bad :P .. – Overly Excessive Dec 16 '14 at 12:37

3 Answers3

3

Add a swap operator/function:

let swap f = fun x y -> f y x
let aList = [2;4;6;8]
let mut = aList |> List.map (swap (/) 2)
Mau
  • 14,234
  • 2
  • 31
  • 52
  • Yes I could do that but I don't think it's very helpful. If I had to resort to adding helper functions I might as well add this `let divByTwo x = x / 2`. – Overly Excessive Dec 15 '14 at 11:43
  • 4
    Well, `swap` in this case is quite general and handy in a variety of use cases. – Mau Dec 15 '14 at 11:44
3

Use flip operator:

 let aList = [2;4;6;8]
 let (<.>) f a b = f b a
 let mut = aList |> List.map ((/) <.> 2)
rkrahl
  • 1,159
  • 12
  • 18
0

I defined the MinusBy, DivBy, function:

/// Minus, easy for pipe forward
let inline MinusBy y x = x - y

/// Division, easy for pipe forward
let inline DivBy y x = x / y

How I find it useful in my statistics library:

// https://en.wikipedia.org/wiki/Normalization_(statistics)
let average = 2.0
let stdev = 3.0     // Standard Deviation
let Standardize (x:double) =
    x |> MinusBy average |> DivBy stdev

I got the idea from other users from my question:

F#, Pipe-forward first argument

CH Ben
  • 1,583
  • 13
  • 23