Skip to content

Instantly share code, notes, and snippets.

Icelandjack /
Last active Apr 23, 2022
Type Classes and Constraints

Reddit discussion.

Disclaimer 1: Type classes are great but they are not the right tool for every job. Enjoy some balance and balance to your balance.

Disclaimer 2: I should tidy this up but probably won’t.

Disclaimer 3: Yeah called it, better to be realistic.

Type classes are a language of their own, this is an attempt to document features and give a name to them.

View gist:660ccce86d4461fd467638368f0d1ac2

Total Type Families

A total type family feels quite comfortable. By total here, I mean a type family whose equations cover all the possible cases and which is guaranteed to terminate. That is, a total type family is properly a function on types. Those other dependently typed languages have functions on types, and they seem to work nicely. I am completely unbothered by total type families.

What are type families?

Non-covering Type Families (are strange)

> A non-covering type family is a type family whose patterns do not cover the whole space.

Icelandjack /
Last active Jan 30, 2017
Deriving for Classes

Just like you can derive instances for data types (example is from homoiconic)

data Foo = F Int Bool 
 deriving Show

maybe it makes sense to do it for certain type classes.

If you define

Icelandjack /
Last active Aug 25, 2017
Playing around with GHC Trac ticket #12369

Are these examples of


data App0 :: Type -> Type where
  App0 :: a -> App0
Icelandjack / TypeApp.markdown
Last active Sep 6, 2018
Examples of Type Application for Infix Operators
View TypeApp.markdown


Showing where types change:

infixr 5 :::
data Nest a = N | a ::: Nest (a, a)


View OneZero.markdown


data One a = One
  deriving Functor

instance Distributive One where
  distribute :: Functor f => f (One a) -> One (f a)
  distribute _ = One
View or-patterns_as_expressions.markdown
View Functors.markdown

HList : Sublist -> Hask

type Cat k = k -> k -> Type

data Sublist :: Cat [a] where
  Stop :: Sublist '[] '[]
  Drop :: Sublist xs ys -> Sublist (x:xs) ys
  Keep :: Sublist xs ys -> Sublist (x:xs) (x:ys)
View Deriving.markdown

One of the best parts of Haskell is getting functionality for free

newtype T a = T_ (Compose [] Maybe a) 
  deriving (Functor, Foldable, Traversable, Applicative, Alternative)

{-# Complete T #-}
pattern T :: [Maybe a] -> T a
pattern T a = T_ (Compose a)
View NewtypeDeriving.markdown