Personal tools

Comparing class alias proposals

From HaskellWiki

Jump to: navigation, search



  • the designer of a class or class hierarchy;
  • the author of class instances;
  • the programmer using the classes and instances.

Furthermore, most motivations can be grouped into two categories:

  • changing an existing API while maintaining backwards compatibility.


1 List of proposals


2 Context synonyms


context BoundedEnum a = (Bounded a, Enum a)

A context synonym may appear anywhere a context is allowed:

  • in the type signature of a function;
  • in a data type or constructor;
  • in a superclass constraint.


Bounded, Enum, BoundedEnum :: * -> Context
Input :: (* -> *) -> *

Context synonyms are synonymous and interchangable with their right-hand sides, much like type synonyms. They are distinct from class aliases in that they do not define any new classes (dictionaries), functions or defaults. Ideally, they can be exported and documented, just like type synonyms.


3 Higher-order context synonyms

Possible additions to the context synonyms include:

Q: May a CS's RHS refer to other CS's? For example:




context Bar a = a Int


Q: May CS's be passed as arguments to other CS's? For example:

context Biz = Bar BoundedEnum

Q: May CS's be partially applied? Consider these alternate definitions of BoundedEnum:

context BoundedEnum a = (Bounded, Enum) a
context BoundedEnum = (Bounded, Enum)

Currently the , separator can be seen as having kind Context -> Context -> Context, but the example above would make this more generic: k -> k -> k.


4 Instances of class aliases



instance Num a where
  zero        = ...
  (+)         = ...
  (-)         = ...
  negate      = ...
  one         = ...
  (*)         = ...
  fromInteger = ...



John's proposal can be decomposed into two smaller steps:

  • then replacing the several type classes by a class alias.

Q: What if an instance header expands to several instances of the same class?

For example, a class alias instance could expand to:

instance (Functor [], Functor Maybe) where

Then multiple fmaps need to be defined. Which is which?

Q: What if an instance is made of several classes with overlapping function names?

Currently function definitions in a class may not be qualified; only the class name in instance header may be qualified. Being able to write several instances under one header introduces naming problems in this case.

Q: What if a class alias expands to many classes, of which one already has an instance in scope?

Should we forbid such an instance and force the programmer to expand the class alias manually to all classes except the one of which there is an instance of already?

Or should such an instance still be allowed, but the implementation of the violating class be forbidden? It seems like a bad idea to allow this without making such an omission clear and explicit in the syntax.

4.1 Class alias or context synonym?


Clearly there are many differences between the two. Their intended uses are originally different. Should they be two different things instead?

Class aliases (in the case of writing instances of them) seem like a strict subset of context synonyms. If class aliases are to piggyback on context synonyms, then we need to think carefully about what form such a context synonym should have for instances to make sense.

5 Overriding superclass defaults

5.1 In normal type classes


class Functor f => Applicative f where
  pure :: a -> f a

In current Haskell, the header means two things:



instance Applicative f => Functor f where
  fmap = (<*>) . pure



class Functor f => Applicative f where
  pure :: a -> f a

  fmap = (<*>) . pure


5.2 In context aliases

6 Adding new functions