prob-fx-0.1.0.2: src/FindElem.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{- | Auxiliary definitions for finding a type in a type-level list.
-}
module FindElem (
FindElem(..)
, Idx(..)) where
import GHC.TypeLits ( TypeError, ErrorMessage(Text, (:<>:), (:$$:), ShowType) )
-- | Proof that @x@ is an element of the type-level list @xs@
class FindElem x xs where
findElem :: Idx x xs
-- | The integer index of @x@ in @xs@
newtype Idx x xs = Idx {unIdx :: Int}
instance FindElem x (x ': xs) where
findElem = Idx 0
instance {-# OVERLAPPABLE #-} FindElem x xs => FindElem x (x' : xs) where
findElem = Idx $ 1 + unIdx (findElem :: Idx x xs)
instance TypeError ('Text "Cannot unify effect types." ':$$:
'Text "Unhandled effect: " ':<>: 'ShowType x ':$$:
'Text "Perhaps check the type of effectful computation and the sequence of handlers for concordance?")
=> FindElem x '[] where
findElem = error "unreachable"