Safe Haskell | Safe-Inferred |
---|---|

Language | Haskell98 |

Overture is an alternative to some of the Prelude. It aims to make Haskell easier to read by providing a few well-named functions and operators.

Overture does not export anything that conflicts with the Prelude. Whenever possible, it tries not to conflict with any other well-known packages. The recommended way to use Overture is to import it unqualified.

`>>>`

`import Overture`

## Motivation

I have been using Haskell for more than I year. In that time, I created libraries and executables. I deployed Haskell to production at my day job. I wrote several blog posts about Haskell. All this to say that I'm not a complete beginner.

Yet I sometimes have trouble undestanding Haskell code. Usually function composition and pointfree expressions are to blame. To me, they read backwards. Take this function for example.

`>>>`

`let f = negate . recip . succ`

Is it immediately obvious to you what this does? If so, this package probably isn't for you. For me, I start reading "negate" before I realize that this is a chain of composed functions, which means I have to start at the end. Eventually I end up understanding that this function adds one, then takes the reciprocal, then negates.

`>>>`

-0.25`f 3`

Let's explore some alternative ways to write this function.

`>>>`

`let f1 x = negate . recip . succ $ x`

`>>>`

`let f2 x = negate . recip $ succ x`

`>>>`

`let f3 x = negate (recip (succ x))`

Of those, I like reading `f3`

the best. But the parentheses add some visual
noise and we still have to understand it from the inside out. Let's see how
you might write this function with Overture.

`>>>`

`let f4 x = negate <. recip <. succ <| x`

`>>>`

`let f5 x = negate <. recip <| succ x`

`>>>`

`let f6 = negate <. recip <. succ`

`>>>`

`let f7 = succ .> recip .> negate`

`>>>`

`let f8 x = succ x |> recip .> negate`

`>>>`

`let f9 x = x |> succ .> recip .> negate`

`f6`

is basically the same as the original `f`

, but it hints at which way
the data will be flowing through it. `f9`

is my favorite because I can
easily see that I take some value and apply a series of transformations to
it. If I wanted to express this function in the pointfree style, I would
prefer `f7`

because it reads from left to right.

# Function composition

compose :: (a -> b) -> (b -> c) -> a -> c Source

Function composition.
This is like the `.`

operator from the Prelude.

This function combines two other functions. The result of

is a new function that applies `compose`

f g`f`

first and then applies `g`

. In other
words,

is the same as `compose`

f g x`g (f x)`

.

`>>>`

`let f = compose succ recip`

`>>>`

0.1`f 9`

Composing many functions together quickly becomes unwieldy. Use `.>`

or
`<.`

instead.

`>>>`

`let g = succ `compose` recip `compose` negate`

`>>>`

-0.1`g 9`

(.>) :: (a -> b) -> (b -> c) -> a -> c infixl 9 Source

Left-associative `compose`

operator.
This is like a flipped version of the `.`

operator from the Prelude.
It is also similar to the `>>>`

operator from
Control.Category.

This operator combines two other functions more naturally than `compose`

.
The result of `f `

is a new function that applies `.>`

g`f`

first and then
applies `g`

.

`>>>`

`let f = succ .> recip`

`>>>`

0.1`f 9`

When reading code, pronounce this operator as "and then". So the above
example could be read as: "Add one, *and then* take the reciprocal."

Thanks to its high precedence, composing many functions together is easy with this operator.

`>>>`

`let g = succ .> recip .> negate`

`>>>`

-0.1`g 9`

(<.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 Source

Right-associative `compose`

operator.
This is like the `.`

operator from the Prelude.
It is also similar to the `<<<`

operator from
Control.Category.

Sometimes it is more convenient to combine functions from right to left.
The result of `g `

is a new function that applies `<.`

f`g`

but first
applies `f`

.

`>>>`

`let f = recip <. succ`

`>>>`

0.1`f 9`

Pronounce this operator as "but first" when reading code. The example above
could be read as: "Take the reciprocal, *but first* add one."

Composing many functions together is easy with this operator thanks to its high precedence.

`>>>`

`let g = negate <. recip <. succ`

`>>>`

-0.1`g 9`

# Function application

apply :: a -> (a -> b) -> b Source

Function application.
This is like the `$`

operator from the Prelude.

This function applies an argument to function.

`>>>`

5`apply 4 succ`

Using this function to apply many arguments is cumbersome. Use `|>`

or `<|`

instead.

`>>>`

0.2`4 `apply` succ `apply` recip`

This function usually isn't necessary since

is the same as
`apply`

x f`f x`

. However it can come in handy when working with higher-order
functions.

`>>>`

[5.0,0.25]`map (apply 4) [succ, recip]`

(|>) :: a -> (a -> b) -> b infixl 0 Source

Left-associative `apply`

operator.
This is like a flipped version of the `$`

operator from the Prelude.

This operator applies an argument to a function. The result of `x `

is `|>`

f`f x`

.

`>>>`

5`4 |> succ`

Since this operator has such low precedence, it can be used to remove parentheses in complicated expressions.

`>>>`

0.2`4 |> succ |> recip`

When reading code, pronounce this operator as "pipe into". So the above
example can be read as: "Four *piped into* plus one, *piped into* the
reciprocal."

It can also be used with higher-order functions, although `apply`

might be
clearer.

`>>>`

[5.0,0.25]`map (4 |>) [succ, recip]`

(<|) :: (a -> b) -> a -> b infixr 0 Source

Right-associative `apply`

operator.
This is like the `$`

operator from the Prelude.

Sometimes it is more convenient to apply arguments right to left. The
result of `f `

is `<|`

x`f x`

.

`>>>`

5`succ <| 4`

Like `|>`

, this operator has low precedence so it can be used to remove
parentheses.

`>>>`

0.2`recip <| succ <| 4`

Pronounce this operator as "pipe from" when reading code. The example above
can be read as: "The reciprocal *piped from* plus one, *piped from* five."

This operator is a convenient alternative to `flip `

.`apply`

`>>>`

[5.0,0.25]`map (<| 4) [succ, recip]`

## Strict function application

apply' :: a -> (a -> b) -> b Source

Strict function application.
This is like the `$!`

operator from the Prelude.

This is the strict version of `apply`

. It evaluates its argument with
`seq`

before applying it to the given function. In other words,

is the same as `apply'`

x f`x `seq` `

.`apply`

x f

`>>>`

*** Exception: Prelude.undefined`apply' undefined (const 0)`