applyFlipped, ‘#’

Type signature:

applyFlipped ::  a b. a -> (a -> b) -> b

Compare with apply:

       apply ::  a b. (a -> b) -> a -> b
applyFlipped ::  a b. a -> (a -> b) -> b

Given the type signatures, it is clear that applyFlipped is really the flipped version of apply. Under the light of that piece of insight, one way to implement applyFlipped is in terms of apply.

applyFlipped ::  a b. a -> (a -> b) -> b
applyFlipped = flip apply

By writing applyFlipped in terms of apply, we can make it point-free.

Or we can write it “manually”, without reusing apply:

applyFlipped ::  a b. a -> (a -> b) -> b
applyFlipped x f = f x

This is how we would use it. Let’s compare with apply:

> apply show 1
"1"

> applyFlipped 1 show
"1"

We apply the show function to the value 1, or, using the flipped version, we first provide the value, then the function.

apply f to x or apply x to f

We have function application, not value application. By definition, it is correct to say that “we apply a function to a value”, and not that “we apply a value to a function”. Still, it is becoming more common to say or write both interchangeably. See my question about this on the PureScript Discord server.

> import Prelude (show, identity)

> apply show 1
"1"

> applyFlipped 1 show
"1"

> apply show (identity 1)
"1"

> applyFlipped (identity 1) show
"1"

Using ‘#’ (number/hash/pound symbol) infixl applyFlipped operator

Whatever implementation we may chose for applyFlipped, we can write it as an infixl operator:

applyFlipped ::  a b. a -> (a -> b) -> b
applyFlipped = flip apply

infixl 0 applyFlipped as #

Here too, as in apply, we need the precedence to be 0 (the lowest possible) so we first evaluate things on the left (infixl) and only then evalutate things on the right.

And some examples of its use (comparing with $/apply):

> import Effect.Console (log)
> import Prelude (identity, show)

> log $ show $ identity 1
1

> identity 1 # show # log
1

The # operator makes it more readable (at last to some people). In the book Functional Programming Made Easier, Charles Scalfani shows an example comparing $ and #:

f x $ step3 $ step2 $ step1 x
f x $ step1 # step2 # step3 x

Indeed, # (applyFlipped) does help with readability and reasoning about code in some situations.

If you have ever used Ramda, apply is like compose(), while applyFlipped is like pipe().