SAm
SAm

Reputation: 2232

Reversing partial function parameters sequence

I want to write List.map (fun x -> x % 3) into a form like List.map ((%) 3).
The issue with the latter is that it translates to
List.map (fun x -> 3 % x) Not what I want.

Is it possible to write List.map (fun x -> x % 3). in a more succinct fashion?

Further context
New to F#. Find it nice to be able to write succinct expressions with partial applications.

E.g. for the logic add 3 to each item in list can be written just as List.map ((+) 3).

However, this doesn't apply to positional sensitive ops like division and modulus.
E.g. I read List.map ((/) 3) as - for each item in list, divide by 3.
But the actual logic is actually mapping 3 divided each item.

[12; 24; 36; 48] |> List.map ((/) 3)
// expect [4; 8; 12; 16]
// actual [3/12; 3/24; 3/36; 3/48] // type discrepancy. but just an example.

From JL0PD's answer, I think what I want is not possible with F# (at the moment).


Retrospect

What I want is not feasible due to the nature of currying/parameter positioning. E.g.
(/) 12 3 = 12 / 3  // left hand op and right hand op are equivalent.
// val it: bool = true

Upvotes: 2

Views: 134

Answers (2)

pjaras
pjaras

Reputation: 11

I fully agree with JL0PD' answer . One more alternative is that you can define your own operator. i.e.

let (%.) x y = y % x 
[12; 24; 36; 48] |> List.map ((%.) 3)

Upvotes: 1

JL0PD
JL0PD

Reputation: 4508

Common workaround for functions that have incorrect order of parameters is flip function

let flip f x y = f y x

With this function you can write

List.map (flip (%) 3)

A bit less universal, but more clear is to create specialized function, like mod

let mod y x = x % y
List.map (mod 3)

But I don't think that that's increases readability and/or maintainability. I would use current version instead

Upvotes: 4

Related Questions