Is it possible to write tacit functions in F#
-
05-07-2019 - |
Question
Tacit or point-free style programming allows one to create functions without regard to their arguments. Can this be done in F#?
Solution
Just to go with Chuck's answer & Chris Smiths' comment, you could write
let digits = string_of_int >> String.length
digits 9000;; // 4
[1; 10; 100] |> List.map digits;; // [1;2;3]
When you combine those composition & pipeline operators with higher-order functions, you can do complicated stuff very succinctly:
let prodSqrtAbs = Seq.map (abs>>sqrt) >> Seq.reduce (*)
prodSqrtAbs [| -9.0; 4.0 |];; // 6.0
EDIT: I just read about J and its implicit fork operator. That is very powerful. You can build equivalent higher-order operators in F#, but they won't be applied implicitly. So, for example, first define lift
(using explicit arguments)
let lift op a b x = op (a x) (b x)
and then apply it explicitly
let avg = lift (/) List.sum List.length
to get something resembling the J example on the Wikipedia page you linked to. But its not quite "tacit."
OTHER TIPS
Sure. All you need is function composition and currying, and both of these are possible in F#.
let compose f1 f2 = fun x -> f1 (f2 x);;
let digits = compose String.length string_of_int;;
digits 9000;; // 4