HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleadjunctions-4.4.3Haskell2010

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.

  • 3 types
  • 1 class
  • 27 values

Representable Functors

2 declarations
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

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

Constructors

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

Default definitions

0 declarations

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