Search code examples
f#tacit-programming

Tacit programming style using F#


It's not a practically important issue, but I'd like to see an example of tacit programming in F# where my point-free functions can have multiple arguments (not in form of a list or tuple).

And secondly, how such functions can manipulate a complex data structure. I'm trying it out in F# Interactive, but have no success yet.

I tried, for instance:

> (fun _ -> (fun _ -> (+))) 333 222 111 555

Is that right way?

And:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";;  

val it : string = "cd"

Solution

  • F# doesn't contain some of the basic functions that are available in Haskell (mainly because F# programmers usually prefer the explicit style of programming and use pointfree style only in the most obvious cases, where it doesn't hurt readability).

    However you can define a few basic combinators like this:

    // turns curried function into non-curried function and back
    let curry f (a, b) = f a b
    let uncurry f a b = f (a, b)
    
    // applies the function to the first/second element of a tuple
    let first f (a, b) = (f a, b)
    let second f (a, b) = (a, f b)
    

    Now you can implement the function to add lengths of two strings using combinators as follows:

    let addLengths = 
      uncurry (( (first String.length) >> (second String.length) ) >> (curry (+)))
    

    This constructs two functions that apply String.length to first/second element of a tuple, then composes them and then adds the elements of the tuple using +. The whole thing is wrapped in uncurry, so you get a function of type string -> string -> int.