Video tutorial

Typeclasses

beginner

Typeclasses are interfaces that define a set of extension functions associated to one type. You may see them referred as “extension interfaces”.

The other purpose of these interfaces, like with any other unit of abstraction,
is to have a single shared definition of a common API and behavior shared across many types in different libraries and codebases.

What differentiates FP from OOP is that these interfaces are meant to be implemented outside of their types, instead of by the types.
Now, the association is done using generic parametrization rather than subclassing by implementing the interface. This has multiple benefits:

Typeclasses can be implemented for any class, even those not in the current project

You can treat typeclass implementations as stateless parameters because they’re just a collection of functions

You can make the extensions provided by a typeclass for the type they’re associated with by using functions like run and with.

You can read all about how Arrow implements typeclasses in the glossary.
If you’d like to use typeclasses effectively in your client code you can head to the docs entry about dependency injection.

Example

Let’s define a typeclass for the behavior of equality between two objects, and we’ll call it Eq:

interfaceEq<T>{funT.eqv(b:T)funT.neqv(b:T)=!eqv(b)}

For this short example we will make available the scope of the typeclass Eq implemented for the type String, by using run.
This will make all the Eq extension functions, such as eqv and neqv, available inside the run block.

Structure

This section uses concepts explained in the glossary like Kind,
make sure to check them beforehand or else jump to the next section.

A few typeclasses can be defined for values, like Eq above, and the rest are defined for type constructors defined by Kind<F, A> using a For- marker.
All methods inside a typeclass will have one of two shapes:

Constructor: create a new Kind<F, A> from a value, a function, an error… Some examples are just, raise, async, defer, or binding.

Extensions: add new functionality to a value A or a container Kind<F, A>, provided by an extension function. For example, map, eqv, show, traverse, sequence, or combineAll.

You can use typeclasses as a DSL to access new extension functions for an existing type,
or treat them as an abstraction placeholder for any one type that can implement the typeclass.
The extension functions are scoped within the typeclass so they do not pollute the global namespace!

To assure that a typeclass has been correctly implemented for a type, Arrow provides a test suite called the “laws” per typeclass.
These test suites are available in the module arrow-tests.

Typeclasses provided by Arrow

We will list all the typeclasses provided in Arrow grouped by the module they belong to, and a short description of the behavior they abstract.

Typeclasses

The package typeclasses contains all the typeclass definitions that are general enough not to be part of a specialized package.
We will list them by their hierarchy.