Chapter 7. Interfaces: using constrained generic types

 

This chapter covers

  • Constraining generic types using interfaces
  • Implementing interfaces for specific contexts
  • Using interfaces defined in the Prelude

In chapter 2, you saw that generic function types with type variables could be constrained so that the variables stood for a more limited set of types. For example, you saw the following function for doubling a number in any numeric type:

double : Num a => a -> a
double x = x + x

The type of double includes a constraint, Num a, which states that a can only stand for numeric types. Therefore, you can use double with Int, Nat, Integer, or any other numeric type, but if you try to use it with a non-numeric type, such as Bool, Idris will report an error.

You’ve seen a few such constraints, such as Eq for types that support equality tests and Ord for types that support comparisons. You’ve also seen functions that rely on other constraints that we haven’t discussed in detail, such as map and >>=, which rely on Functor and Monad, respectively. We haven’t yet discussed how these constraints are defined or introduced.

In this chapter, we’ll discuss how to define and use constrained generic types using interfaces. In the type declaration for double, for example, the constraint Num a is implemented by an interface, Num, which describes arithmetic operations that will be implemented in different ways for different numeric types.


Type classes in Haskell

7.1. Generic comparisons with Eq and Ord

7.1.1. Testing for equality with Eq

7.1.2. Defining the Eq constraint using interfaces and implementations

7.1.3. Default method definitions

7.1.4. Constrained implementations

7.1.5. Constrained interfaces: defining orderings with Ord

7.2. Interfaces defined in the Prelude

7.2.1. Converting to String with Show

7.2.2. Defining numeric types

7.2.3. Converting between types with Cast

7.3. Interfaces parameterized by Type -> Type

7.3.1. Applying a function across a structure with Functor

7.3.2. Reducing a structure using Foldable

7.3.3. Generic do notation using Monad and Applicative

7.4. Summary