{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Constraint.Bare
( BareConstraint, pattern DictValue
, dictToBare, bareToDict
, withBareConstraint
) where
import Data.Constraint (Dict (..))
import GHC.Base (Constraint, Type)
#if __GLASGOW_HASKELL__ >= 900
import GHC.Exts (unsafeCoerce#)
#else
import GHC.Base (unsafeCoerce#)
#endif
data BareConstraint :: Constraint -> Type
pattern DictValue :: BareConstraint c -> Dict c
pattern DictValue c <- (dictToBare -> c)
where
DictValue c = bareToDict c
#if __GLASGOW_HASKELL__ >= 802
{-# COMPLETE DictValue #-}
#endif
dictToBare :: forall c . Dict c -> BareConstraint c
dictToBare Dict = case (unsafeCoerce# id :: Magic c (BareConstraint c)) of Magic c -> c
{-# INLINE dictToBare #-}
bareToDict :: forall c . BareConstraint c -> Dict c
bareToDict = unsafeCoerce# (Magic Dict :: Magic c (Dict c))
{-# INLINE bareToDict #-}
withBareConstraint :: forall c r . BareConstraint c -> (c => r) -> r
withBareConstraint bc f = unsafeCoerce# (Magic f :: Magic c r) bc
newtype Magic c r = Magic (c => r)