{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Constraint.Emerge
( Emerge
, emerge
, Dict (..)
) where
import Data.Constraint
------------------------------------------------------------------------------
-- | Typeclass asserting we can determine the existence of the constraint 'c'
-- at runtime.
class Emerge (c :: Constraint) where
emerge' :: Maybe (Dict c)
------------------------------------------------------------------------------
-- | Get a dictionary for 'c' if it exists.
emerge :: Emerge c => Maybe (Dict c)
emerge = emerge'
------------------------------------------------------------------------------
-- | A typeclass whose dictionaries we can coerce into those for 'Emerge' if
-- our constraint wasn't satisfied.
class AlwaysFail where
alwaysFail :: Maybe (Dict a)
instance AlwaysFail where
alwaysFail = Nothing
------------------------------------------------------------------------------
-- | A typeclass whose dictionaries we can coerce into those for 'Emerge' if
-- our constraint was satisfied.
class Succeed (a :: Constraint) where
succeed :: Maybe (Dict a)
instance c => Succeed c where
succeed = Just Dict