HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulerow-types-1.0.1.2Haskell2010

Data.Row.Dictionaries

This module exports various dictionaries that help the type-checker when dealing with row-types.

For the various axioms, type variables are consistently in the following order:

  • Any types that do not belong later.

  • Labels

  • Row-types

    • If applicable, the type in the row-type at the given label goes after each row-type

  • Constraints

  • 6 types
  • 6 classes
  • 25 values

Axioms

25 declarations
valueextendHas :: Dict ((Extend l t r .! l) ≈ t)
#

If we know that r has been extended with l .== t, then we know that this extension at the label l must be t.

valueapHas :: ((ϕ .! l) ≈ f, (ρ .! l) ≈ t) :- ((Ap ϕ ρ .! l) ≈ f t, (Ap ϕ ρ .- l) ≈ Ap (ϕ .- l) (ρ .- l))
#

This allows us to derive Ap ϕ ρ .! l ≈ f t from ϕ .! l ≈ f and ρ .! l ≈ t

Helper Types

classclass IsA (c :: k -> Constraint) (f :: k -> k1) (a :: k1) where
#

A class to capture the idea of As so that it can be partially applied in a context.

Methods

Instances1IsA
  • c a => IsA c f (f a)Defined in row-types-1.0.1.2 · Data.Row.Dictionaries
datadata As (c :: k -> Constraint) (f :: k -> k1) (a :: k1) where
#

This data type is used to for its ability to existentially bind a type variable. Particularly, it says that for the type a, there exists a t such that a ~ f t and c t holds.

Constructors

  • As :: (a ~ f t, c t) => As c f a
classclass ActsOn (c :: (k -> k1) -> Constraint) (t :: k) (a :: k1) where
#

A class to capture the idea of As' so that it can be partially applied in a context.

Methods

Instances1ActsOn
  • c f => ActsOn c t (f t)Defined in row-types-1.0.1.2 · Data.Row.Dictionaries
datadata As' (c :: (k -> k1) -> Constraint) (t :: k) (a :: k1) where
#

Like As, but here we know the underlying value is some f applied to the given type a.

Constructors

Re-exports

8 declarations
datadata Dict (a :: Constraint) where
#

Values of type Dict p capture a dictionary for a constraint of type p.

e.g.

Dict :: Dict (Eq Int)

captures a dictionary that proves we have an:

instance Eq Int

Pattern matching on the Dict constructor will bring this instance into scope.

Constructors

Instances20:=>, HasDict, Bounded, Enum, Eq, Data, …
  • () :=> Semigroup (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • () :=> Show (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • () :=> Eq (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • () :=> Ord (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a :=> Monoid (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a :=> Bounded (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a :=> Enum (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a :=> Read (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • HasDict a (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a => Bounded (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a => Enum (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • Eq (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • (Typeable p, p) => Data (Dict p)Defined in constraints-0.14.2 · Data.Constraint
  • Ord (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a => Read (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • Show (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • Semigroup (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • a => Monoid (Dict a)Defined in constraints-0.14.2 · Data.Constraint
  • NFData (Dict c)Defined in constraints-0.14.2 · Data.Constraint
  • c => Boring (Dict c)Defined in constraints-0.14.2 · Data.Constraint
newtypenewtype (:-) (a :: Constraint) (b :: Constraint)
#

This is the type of entailment.

a :- b is read as a "entails" b.

With this we can actually build a category for Constraint resolution.

e.g.

Because Eq a is a superclass of Ord a, we can show that Ord a entails Eq a.

Because instance Ord a => Ord [a] exists, we can show that Ord a entails Ord [a] as well.

This relationship is captured in the :- entailment type here.

Since p :- p and entailment composes, :- forms the arrows of a Category of constraints. However, Category only became sufficiently general to support this instance in GHC 7.8, so prior to 7.8 this instance is unavailable.

But due to the coherence of instance resolution in Haskell, this Category has some very interesting properties. Notably, in the absence of IncoherentInstances, this category is "thin", which is to say that between any two objects (constraints) there is at most one distinguishable arrow.

This means that for instance, even though there are two ways to derive Ord a :- Eq [a], the answers from these two paths _must_ by construction be equal. This is a property that Haskell offers that is pretty much unique in the space of languages with things they call "type classes".

What are the two ways?

Well, we can go from Ord a :- Eq a via the superclass relationship, and then from Eq a :- Eq [a] via the instance, or we can go from Ord a :- Ord [a] via the instance then from Ord [a] :- Eq [a] through the superclass relationship and this diagram by definition must "commute".

Diagrammatically,

                   Ord a
               ins /     \ cls
                  v       v
            Ord [a]     Eq a
               cls \     / ins
                    v   v
                   Eq [a]

This safety net ensures that pretty much anything you can write with this library is sensible and can't break any assumptions on the behalf of library authors.

Constructors

Instances10Category, :=>, HasDict, Eq, Data, Ord, …
  • Category (:-)Defined in constraints-0.14.2 · Data.Constraint

    Possible since GHC 7.8, when Category was made polykinded.

  • () :=> Show (a :- b)Defined in constraints-0.14.2 · Data.Constraint
  • () :=> Eq (a :- b)Defined in constraints-0.14.2 · Data.Constraint
  • () :=> Ord (a :- b)Defined in constraints-0.14.2 · Data.Constraint
  • a => HasDict b (a :- b)Defined in constraints-0.14.2 · Data.Constraint
  • Eq (a :- b)Defined in constraints-0.14.2 · Data.Constraint

    Assumes IncoherentInstances doesn't exist.

  • (Typeable p, Typeable q, p => q) => Data (p :- q)Defined in constraints-0.14.2 · Data.Constraint
  • Ord (a :- b)Defined in constraints-0.14.2 · Data.Constraint

    Assumes IncoherentInstances doesn't exist.

  • Show (a :- b)Defined in constraints-0.14.2 · Data.Constraint
  • a => NFData (a :- b)Defined in constraints-0.14.2 · Data.Constraint
classclass HasDict (c :: Constraint) e | e -> c where
#

Witnesses that a value of type e contains evidence of the constraint c.

Mainly intended to allow (\\) to be overloaded, since it's a useful operator.

Methods

Instances6HasDict
value(\\) :: HasDict c e => (c => r) -> e -> r
#

Operator version of withDict, with the arguments flipped

valuewithDict :: HasDict c e => e -> (c => r) -> r
#

From a Dict, takes a value in an environment where the instance witnessed by the Dict is in scope, and evaluates it.

Essentially a deconstruction of a Dict into its continuation-style form.

Can also be used to deconstruct an entailment, a :- b, using a context a.

withDict :: Dict c -> (c => r) -> r
withDict :: a => (a :- c) -> (c => r) -> r
classclass Unconstrained1 (a :: k)
#

A null constraint of one argument

Instances1Unconstrained1
classclass Unconstrained2 (a :: k) (b :: k1)
#

A null constraint of two arguments

Instances1Unconstrained2