first-class-instances: First class typeclass instances

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

See the README file in the project repository


[Skip to Readme]

Properties

Versions 0.1.0.0, 1.0.0.0, 1.0.0.0, 1.0.0.1
Change log CHANGELOG.md
Dependencies base (>=4.13 && <5), containers (>=0.6.0.1 && <0.9), template-haskell (>=2.15 && <2.24), transformers (>=0.6 && <0.7) [details]
License BSD-3-Clause
Copyright 2019 Matej Nižník
Author Matej Nižník
Maintainer lysxia@gmail.com
Category Language
Source repo head: git clone https://gitlab.com/thematten/first-class-instances
Uploaded by lyxia at 2025-07-29T17:32:54Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for first-class-instances-1.0.0.0

[back to package description]

First-class instances

GHC compiles type classes as data types. first-class-instaces makes that correspondence explicit with a simple but powerful mechanism to define instances. This enables implementations of deriving as libraries.

Overview

Type classes as data types

Type classes are associated to data types using the mkDict command.

Example:

class Monoid a where
  mempty :: a
  (<>) :: a -> a -> a

mkDict ''Monoid

That generates the following data type:

data DictMonoid a = Monoid
  { _mempty :: a
  , (|<>) :: a -> a -> a
  }

Dictionaries

The Dict type family maps constraints to their corresponding dictionary types.

type family Dict (c :: Constraint) :: Type    -- Defined in FCI

type instance Dict (Monoid a) = DictMonoid a  -- also from mkDict ''Monoid

A constraint c can be reflected as a dictionary:

dict @c :: c => Dict c

Instances from dictionaries

A dictionary d can be reified as an instance.

Example:

instanceDict [| d :: Dict (Monoid T) |]

That generates the following instance:

instance Monoid T where
  mempty = _mempty d
  (<>) = (|<>) d

Show me the types

The core API of first-class-instances:

{- module FCI -}

type Dict :: Constraint -> Type

dict :: forall c. c => Dict c

mkDict :: Name -> Q [Dec]

instanceDict :: Q Type -> Q [Dec]


{- module FCI.Unsafe -}

(==>) :: forall c r. Dict c -> (c => r) -> r

Deriving as a library

These simple primitives can be used to implement "deriving as a library". The adventure continues in ad-lib.