{-# LANGUAGE KindSignatures #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeInType #-} module Capability.TypeOf where import Data.Kind (Type) -- | Type family associating a tag to the corresponding type. It is intended to -- simplify constraint declarations, by removing the need to redundantly specify -- the type associated to a tag. -- -- It is poly-kinded, which allows users to define their own kind of tags. -- Standard haskell types can also be used as tags by specifying the 'Type' kind -- when defining the type family instance. -- -- Defining 'TypeOf' instances for 'GHC.TypeLits.Symbol's (typelevel string -- literals) is discouraged. Since symbols all belong to the same global -- namespace, such instances could conflict with others defined in external -- libraries. More generally, as for typeclasses, 'TypeOf' instances should -- always be defined in the same module as the tag type to prevent issues due to -- orphan instances. -- -- Example: -- -- @ -- import Capability.Reader -- -- data Foo -- data Bar -- type instance TypeOf Type Foo = Int -- type instance TypeOf Type Bar = String -- -- -- Same as: foo :: HasReader Foo Int M => … -- foo :: HasReader' Foo m => … -- foo = … -- @ type family TypeOf k (s :: k) :: Type