haskelltype-familiesassociated-types

Multiple type synonyms in a class


Is there a way to define a type synonym in terms of an associated type synonym? (Not sure if I have the right terminology.)

{-# LANGUAGE TypeFamilies #-}

class Reproductive a where

  -- | A sequence of genetic information for an agent.
  type Strand a

  -- | Full set (both strands) of genetic information for an organism.
  type Genome a = (Strand a, Strand a)

Here's the error message I get.

λ> :l stackOverflow.hs 
[1 of 1] Compiling Main             ( stackOverflow.hs, interpreted )

stackOverflow.hs:9:8: error:
    ‘Genome’ is not a (visible) associated type of class ‘Reproductive’
  |
9 |   type Genome a = (Strand a, Strand a)
  |        ^^^^^^
Failed, no modules loaded.

I can just use (Strand a, Strand a) everywhere, but it would be nice to use Genome a.


Solution

  • You can define the type synonym separately from the class:

    {-# LANGUAGE TypeFamilies #-}
      
    -- | Full set (both strands) of genetic information for an organism.
    type Genome a = (Strand a, Strand a)
    
    class Reproductive a where
    
      -- | A sequence of genetic information for an agent.
      type Strand a
    

    Alternatively, if you want to be able to overwrite it for certain instances then you can define it like this:

    {-# LANGUAGE TypeFamilies #-}
    
    class Reproductive a where
    
      -- | A sequence of genetic information for an agent.
      type Strand a
    
      -- | Full set (both strands) of genetic information for an organism.
      type Genome a 
      type Genome a = (Strand a, Strand a)
    

    It seems redundant, but you can think of the first type Genome a as the signature and the second line as the default implementation. In this case the signature is simply type Genome a :: * or type Genome a for short, but it can get more complicated than that.