TL;DR

@@ may be used to group expressions if you’re allergic to parentheses. Example:

List.rev @@ List.sort (-) [4;2;5;2;7;5;4;1;3;9;0]
 

is equivalent to

List.rev (List.sort (-) [4;2;5;2;7;5;4;1;3;9;0])

You can think of @@ as being defined as let (@@) f x = f x, and you’re right, f @@ x isn’t a whole lot different from f x. One use case for @@ is when you’re trying to cut down on parenthesis. For example, consider a pop function that extracts a value from an option:

let pop = function Some x -> x | None -> failwith "nothing here"
 

If you wanted to call it on Some 5, it would be a bit of pain.

pop Some 5
 

would lead to this error

Error: The constructor Some expects 1 argument(s),
       but is applied here to 0 argument(s)
 

You can fix this by either wrapping the option in parenthesis or by using the @@ operator:

pop (Some 5)
 
pop @@ Some 5
 

Both compile as you’d expect.

Edit: I thought I’d mention that this trick works because @@ has lower precedence than other operations (like applying a function or passing an argument into a constructor).

https://www.reddit.com/r/ocaml/comments/3qmapa/comment/cwgfb1b/


🌱 Back to Garden