Skip to content

Define Eq and Ord instances for SSymbol, SChar, and SNat #148

@RyanGlScott

Description

@RyanGlScott

There are four singleton types currently defined in base:

  1. TypeRep, defined in Type.Reflection
  2. SSymbol, defined in GHC.TypeLits
  3. SChar, defined in GHC.TypeLits
  4. SNat, defined in GHC.TypeNats

SSymbol, SChar, and SNat were introduced as part of proposal #85, and their APIs were designed to mimic that of TypeRep. Unfortunately, #85 forgot to carry over one aspect of the TypeRep API: the Eq and Ord instances:

instance Eq (TypeRep a) where
  _ == _  = True

instance Ord (TypeRep a) where
  compare _ _ = EQ

I propose that we define similar Eq and Ord instances for SSymbol, SChar, and SNat.

How?

How can we know that the Eq and Ord instances for TypeRep always return True/EQ? This is because TypeRep is a singleton type. That is, given a fixed type a, there is only ever a single unique value¹ that can inhabit type TypeRep a. Therefore, the equality checks that (==) and compare perform will always succeed by virtue of the typing discipline involved.

The same reasoning applies to all other singleton types, including SSymbol, SChar, and SNat.

Why?

Why bother defining these instances in the first place? On their own, they aren't terribly useful, as (==)/compare will always compute the same answer. They are more useful for the purpose of satisfying superclasses of other instances. For instance, the EqP class in the some library requires a quantified Eq superclass, so it would not be possible to define an EqP instance for TypeRep (or any other singleton type) without first giving it an Eq instance.

Prior art

TypeRep is the most notable singleton type to define Eq/Ord instances in this fashion. Besides TypeRep, I have also found other occurrences of these sort of Eq/Ord instances in the wild:

  1. SNat, defined in singleton-nats
  2. SBool, defined in singleton-bool
  3. BoolRepr, NatRepr, and SymbolRepr, defined in parameterized-utils

¹ Besides , but it is fine to reason modulo .

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedApproved by CLC votebase-4.19Implemented in base-4.19 (GHC 9.8)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions