HORIZON HASKELLDocslts/ghc-10.0.x2b276322026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 2b27632 · 2026-10-31

Moduleadjunctions-4.4.4Haskell2010

Data.Functor.Rep

Representable endofunctors over the category of Haskell types are isomorphic to the reader monad and so inherit a very large number of properties for free.

Contents
  1. Representable Functors
  2. Wrapped representable functors
  3. Default definitions
  4. Functor
  5. Distributive
  6. Apply/Applicative
  7. Bind/Monad
  8. MonadFix
  9. MonadZip
  10. MonadReader
  11. Extend
  12. Comonad
  13. Comonad, with user-specified monoid
  14. WithIndex
  15. Generics
Synopsis

Representable Functors

classclass Distributive f => Representable (f :: Type -> Type) where

A Functor f is Representable if tabulate and index witness an isomorphism to (->) x.

Every Distributive Functor is actually Representable.

Every Representable Functor from Hask to Hask is a right adjoint.

tabulate . index  ≡ id
index . tabulate  ≡ id
tabulate . return ≡ return

Associated types

  • type family Rep (f :: Type -> Type)

    If no definition is provided, this will default to GRep.

Methods

Instances24Representable, …

Wrapped representable functors

newtypenewtype Co (f :: Type -> Type) a
#

Constructors

Instances12ComonadTrans, MonadReader, Monad, Functor, Applicative, Distributive, …

Default definitions

Functor

Distributive

Apply/Applicative

Bind/Monad

MonadFix

MonadZip

MonadReader

Extend

Comonad

Comonad, with user-specified monoid

WithIndex

Generics

typetype GRep (f :: Type -> Type) = GRep' (Rep1 f)

A default implementation of Rep for a datatype that is an instance of Generic1. This is usually composed of Either, tuples, unit tuples, and underlying Rep values. For instance, if you have:

data Foo a = MkFoo a (Bar a) (Baz (Quux a)) deriving (Functor, Generic1)
instance Representable Foo

Then you'll get:

GRep Foo = Either () (Either (WrappedRep Bar) (WrappedRep Baz, WrappedRep Quux))

(See the Haddocks for WrappedRep for an explanation of its purpose.)

newtypenewtype WrappedRep (f :: Type -> Type)

On the surface, WrappedRec is a simple wrapper around Rep. But it plays a very important role: it prevents generic Representable instances for recursive types from sending the typechecker into an infinite loop. Consider the following datatype:

data Stream a = a :< Stream a deriving (Functor, Generic1)
instance Representable Stream

With WrappedRep, we have its Rep being:

Rep Stream = Either () (WrappedRep Stream)

If WrappedRep didn't exist, it would be:

Rep Stream = Either () (Either () (Either () ...))

An infinite type! WrappedRep breaks the potentially infinite loop.

Constructors