Watch video

Video tutorial


Typeclasses define a set of functions associated to one generic type. 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 free functionality 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!

What differentiates typeclasses from regular OOP inheritance is that typeclasses are meant to be implemented outside of their types. The association is done using generic parametrization rather than subclassing by implementing the interface. This has multiple benefits:

  • You can treat typeclass implementations as stateless parameters because they’re just a collection of functions
  • Typeclasses can be implemented for any class, even those not in the current project
  • You can make available any one implementation of a typeclasses at any scope for the generic type they’re associated with by using functions like run and with

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.


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.

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.

import arrow.instances.*

val stringEq = String.eq()

// arrow.instances.StringKt$eq$1@ff0ddb9 {
    && "2".neqv("1")
// false

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.


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.

  • Inject - transformation between datatypes

  • Alternative - has an structure that contains either of two values

  • Show - literal representation of an object
  • Eq - structural equality between two objects

  • Order - determine whether one object precedes another

  • Semigroup - can combine two objects together

  • SemigroupK - can combine two datatypes together

  • Monoid - combinable objects have an empty value

  • MonoidK - combinable datatypes have an empty value

  • Foldable - has a structure from which a value can be computed from visiting each element

  • Bifoldable - same as foldable, but for structures with more than one possible type, like either

  • Reducible - structures that can be combined to a summary value

  • Traverse - has a structure for which each element can be visited and get applied an effect


Effects provides a hierarchy of typeclasses for lazy and asynchronous execution.

  • MonadDefer - can evaluate functions lazily

  • Async - can be created using an asynchronous callback function

  • Effect - can extract a value from an asynchronous function


The Monad Template Library module gives more specialized version of existing typeclasses


  • At - provides a Lens for a structure with an indexable focus

  • FilterIndex - provides a Traversal for a structure with indexable foci that satisfy a predicate

  • Index - provides an Optional for a structure with an indexable optional focus

  • Each - provides a Traversal


  • Corecursive - traverses a structure forwards from the starting case

  • Recursive - traverses a structure backwards from the base case

  • Birecursive - it is both recursive and corecursive