Tacit or point-free style programming allows one to create functions without regard to their arguments. Can this be done in F#?
Asked
Active
Viewed 300 times
2 Answers
6
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."

Gabriel
- 1,443
- 15
- 24
-
Hi, Gabriel. May I ask a question? Does the absence of `implicit fork' operator in FSharp forces me to write only one-argument tacit functions (pack arguments in a tuple/list etc.); but never allows me to write two/three/four/..-argument tacit functions? – Bubba88 May 08 '10 at 10:58
3
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

Chuck
- 234,037
- 30
- 302
- 389
-
I'd have written compose the other way round, that way it would look like the >> operator. – Benjol Nov 27 '09 at 06:35
-
F# has the following operators for doing this sort of thing >>, <<, |>, <|, ||>. – Chris Smith Nov 27 '09 at 07:02