🎓 A1Learner
🔍
0 of 47 lessons completed

Haskell Associated Types

An associated type is a type family that lives inside a typeclass. Each instance of the class fixes the family for its own type.

A list instance fixes Elem to its element type

The list instance sets Elem to the element type. Its elems method returns the list itself.

{-# LANGUAGE TypeFamilies #-}
class Collection c where
  type Elem c
  elems :: c -> [Elem c]
instance Collection [a] where
  type Elem [a] = a
  elems xs = xs
main :: IO ()
main = print (elems [7, 8])

A Maybe instance fixes Elem to its wrapped type

The Maybe instance sets Elem to the wrapped type. Its elems method gives a one element list or an empty list.

{-# LANGUAGE TypeFamilies #-}
class Collection c where
  type Elem c
  elems :: c -> [Elem c]
instance Collection (Maybe a) where
  type Elem (Maybe a) = a
  elems Nothing = []
  elems (Just x) = [x]
main :: IO ()
main = do
  print (elems (Just 9))
  print (elems (Nothing :: Maybe Int))

A default method works through the associated type

Count is defined once in the class. It counts the elements for every instance.

{-# LANGUAGE TypeFamilies #-}
class Collection c where
  type Elem c
  elems :: c -> [Elem c]
  count :: c -> Int
  count c = length (elems c)
instance Collection [a] where
  type Elem [a] = a
  elems xs = xs
main :: IO ()
main = print (count [7, 8, 9])

Example

{-# LANGUAGE TypeFamilies #-}
class Collection c where
  type Elem c
  elems :: c -> [Elem c]
  count :: c -> Int
  count c = length (elems c)
data Box a = Box a
instance Collection [a] where
  type Elem [a] = a
  elems xs = xs
instance Collection (Maybe a) where
  type Elem (Maybe a) = a
  elems Nothing = []
  elems (Just x) = [x]
instance Collection (Box a) where
  type Elem (Box a) = a
  elems (Box x) = [x]
main :: IO ()
main = do
  print (elems [7, 8])
  print (count (Just 9))
  print (elems (Box 5))

Key points

  • Associated type: a type family declared inside a class definition.
  • An associated type is a type chosen by the instance, not by the caller.
  • Each instance fixes the associated type for its own collection type.
  • Use a default method to share code that works through the associated type.
  • The class methods can mention the associated type in their result types.

In this example, Collection declares Elem with elems and a default count. The list, Maybe, and Box instances each fix Elem for their own type. The prints show list elements, the count of a Maybe value, and the elements of a box.

Note

An associated type needs the TypeFamilies language extension.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

In class Collection, what does an instance choose for type Elem c?