Search code examples
syntaxocamlpointfree

Point-free: confused about where to put parenthesis


let list_to_string = (String.concat "") (List.map (String.make 1));;

This is wrong, but how do I make it understand that the argument is still to be supplied? The argument is expected to be of type char list, I.e. the first function that needs to be applied to it is the (List.map (String.make 1)), and then pass it to String.concat "". I think I've tried all combinations of parenthesis I could think of... no joy so far.

Help?

I also figured I could do it like this:

let ($) f g x = f (g x);;
let list_to_string = (String.concat "") $ (List.map (String.make 1));;

But just wanted to make sure there isn't a better way.


Solution

  • The real (and always perplexing) problem is that OCaml doesn't have a built-in function composition operator. So it's not so good out of the box for pointfree coding. If you really want to get fancy with it, you also need flip, which inverts the order of the arguments of a two-argument function.

    let flip f a b = f b a
    

    At any rate, I don't see any problem with your solution once you've defined function composition as $. You can leave out some of the parentheses:

    # let lts = String.concat "" $ List.map (String.make 1);;
    val lts : char list -> string = <fun>
    

    As to efficiency, I assume this is more of a puzzle than a practical bit of code. Otherwise you should use the functions that Edwin suggests.