capability-0.4.0.0: src/Capability/TypeOf.hs
{-# 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