25

Could someone explain what the |> operator does? This code was taken from the reference here:

let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world")

I can see what it does, but I wouldn't know how to apply the |> operator otherwise.

For that matter, I have no idea what the Module.() syntax is doing either. An explanation on that would be nice too.

eatonphil
  • 13,115
  • 27
  • 76
  • 133
  • See [Prefix and Infix Operator](https://dev.realworldocaml.org/variables-and-functions.html#scrollNav-2-4) of [Real World OCaml 2nd ed](https://dev.realworldocaml.org/) for an excellent explanation and examples, where `|>`, the *reverse application operator*, is contrasted with `@@`, the *application operator*. – Hanson Char Jan 29 '23 at 05:19

3 Answers3

33

Module.(e) is equivalent to let open Module in e. It is a shorthand syntax to introduce things in scope.

The operator |> is defined in module Pervasives as let (|>) x f = f x. (In fact, it is defined as an external primitive, easier to compile. This is unimportant here.) It is the reverse application function, that makes it easier to chain successive calls. Without it, you would need to write

let m = PairsMap.(add (1,0) "world" (add (0,1) "hello" empty))

that requires more parentheses.

byako
  • 3,372
  • 2
  • 21
  • 36
  • 3
    To address the specific example that the OP had, it's worth also adding that |> is left associative – Motorhead Apr 01 '21 at 22:42
  • 1
    also called "natural application"/"natural composition" . aka mathematics from left to right, the usual latin way. In mathematics notation, natural composition is written "f;g" (and it's the composition in the opposite category) – nicolas Apr 02 '21 at 12:04
23

The |> operator looks like the | in bash.

The basic idea is that

e |> f = f e

It is a way to write your applications in the order of execution.

As an exemple you could use it (I don't particularly think you should though) to avoid lets:

12 |> fun x -> e

instead of

let x = 12 in e

For the Module.() thing, it is to use a specific function of a given module.

You probably have seen List.map before. You could of course use open List and then only refer to the function with map. But if you also open Array afterwards, map is now referring to Array.map so you need to use List.map.

Théo Winterhalter
  • 4,908
  • 2
  • 18
  • 34
11

The |> operator represents reverse function application. It sounds complicated but it just means you can put the function (and maybe a few extra parameters) after the value you want to apply it to. This lets you build up something that looks like a Unix pipeline:

# let ( |> ) x f = f x;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
# 0.0 |> sin |> exp;;
- : float = 1.

The notation Module.(expr) is used to open the module temporarily for the one expression. In other words, you can use names from the module directly in the expression, without having to prefix the module name.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108