Search code examples
haskellconstraint-kinds

() as empty constraint


how can one represent the empty constraint ?

for the following file

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}

import Data.Kind(Type, Constraint)

type Empty = (() :: Type -> Constraint)

main :: IO ()
main = return ()

ghc 8.2.2 answers

constraint.hs:6:15: error:
    • Expected kind ‘* -> Constraint’, but ‘()’ has kind ‘*’
    • In the type ‘(() :: Type -> Constraint)’
      In the type declaration for ‘Empty’
  |
6 | type Empty = (() :: Type -> Constraint)
  |  

what do i miss ?

i know about the following solution

{-# LANGUAGE FlexibleInstances #-}

class Empty x
instance Empty x

but i want to know why () does not work


Solution

  • () has kind * or Constraint, depending on context, never a -> Constraint. Similarly (,) has kind * -> * -> * or Constraint -> Constraint -> Constraint, depending on context.

    Simon Peyton-Jones

    It’s just that () is only overloaded for whether it’s a type or a constraint. That is, you’d write () => a, not (() a) => a. So I think this:

    class Empty x
    instance Empty x
    

    Is the correct solution here. (And perhaps something like that should be in base.)