Version 6 (modified by ross@…, 11 years ago) (diff)

Issues with Standard Classes

This page collects issues and proposals for the standard classes. Many of the proposals involve additional superclasses, which would be less burdensome with class aliases or something similar, but such features are not yet implemented.

Constructor classes

The Functor class


  • Add instances for ((->) a), ((,) a) and Either a.

The Monad class


  • Monads are really functors, but programmers can't always assume that fmap is defined for them, and so must use liftM instead. Similarly, code parameterized by Functor cannot be used with monads.
  • The fail method was added to the class in Haskell 98 to implement pattern match failure in do expressions. However the assumption that errors are strings can be problematic (e.g. cf the Error class in Control.Monad.Error, or for internationalization).


  • Add instance for ((->) a).
  • Make Functor a superclass of Monad. This would impose an extra burden on those who just want to define a Monad.
  • Make join a method of Monad, interdefined with (>>=).
  • A more extreme step down this road would be to interpose the new Applicative class between Functor and Monad, with corresponding renaming of methods.


The Haskell 98 numeric classes are adequate for Haskell 98 numeric types, but other mathematical objects do not fit. If the Haskell 98 classes were retained for backwards compatibility, but with a more refined class hierarchy, the change would impact mostly on those defining instances (and these are the people inconvenienced by the current system). Clients of the classes would notice only some more general types. See also:

The Num class


  • Eq and Show don't make sense for functions under lifting.
  • (*) doesn't make sense for vectors.
  • abs and signum don't make sense for Complex Integer (Gaussian integers), vectors, matrices, etc.


  • a group-like class with zero, (+) and negate/(-) (could be further split with a monoid sub-class)
  • a ring-like subclass adding (*) and one/fromInteger, with the existing Num class as a further subclass.

Note that the Float and Double instances will not satisfy the usual axioms for these structures.

The Integral class


  • div and mod also sense for rationals and polynomials, but toInteger does not. Ord, Num(abs, signum), toInteger and toRational don't make sense for polynomials. quot and rem assume an ordering.

The Fractional class


  • (/) can be lifted to functions, but many of the pre-requisites can't be defined for these.


  • Add a field-like superclass adding these operations to the ring-like class.
  • Add default
    fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
    This is independent of all the other proposals.

Other standard classes

The Read class

See ReadClass.

The Enum class


  • succ and pred are unused.
  • The default definitions of enum* would make more sense if toEnum and fromEnum used Integer instead of Int.

The Ix class


  • There is no portable way to report indexing errors accurately.


  • Make Show a superclass of Ix, so that the offending index and range can be shown in exceptions. (All instances of Ix in the base package are also instances of Show.)