{-# LANGUAGE CPP, RankNTypes, PolyKinds, DataKinds, TypeOperators,
TypeFamilies, FlexibleContexts, UndecidableInstances,
GADTs, TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}
#if __GLASGOW_HASKELL__ < 806
{-# LANGUAGE TypeInType #-}
#endif
#if __GLASGOW_HASKELL__ >= 810
{-# LANGUAGE StandaloneKindSignatures #-}
#endif
module Data.Singletons.Decide (
SDecide(..),
(:~:)(..), Void, Refuted, Decision(..),
decideEquality, decideCoercion
) where
import Data.Kind
import Data.Singletons
import Data.Type.Coercion
import Data.Type.Equality
import Data.Void
#if __GLASGOW_HASKELL__ >= 810
type Refuted :: Type -> Type
#endif
type Refuted a = (a -> Void)
#if __GLASGOW_HASKELL__ >= 810
type Decision :: Type -> Type
#endif
data Decision a = Proved a
| Disproved (Refuted a)
#if __GLASGOW_HASKELL__ >= 810
type SDecide :: Type -> Constraint
#endif
class SDecide k where
(%~) :: forall (a :: k) (b :: k). Sing a -> Sing b -> Decision (a :~: b)
infix 4 %~
decideEquality :: forall k (a :: k) (b :: k). SDecide k
=> Sing a -> Sing b -> Maybe (a :~: b)
decideEquality :: forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Maybe (a :~: b)
decideEquality Sing a
a Sing b
b =
case Sing a
a Sing a -> Sing b -> Decision (a :~: b)
forall (a :: k) (b :: k). Sing a -> Sing b -> Decision (a :~: b)
forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Decision (a :~: b)
%~ Sing b
b of
Proved a :~: b
Refl -> (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
Disproved Refuted (a :~: b)
_ -> Maybe (a :~: b)
forall a. Maybe a
Nothing
instance SDecide k => TestEquality (WrappedSing :: k -> Type) where
testEquality :: forall (a :: k) (b :: k).
WrappedSing a -> WrappedSing b -> Maybe (a :~: b)
testEquality (WrapSing Sing a
s1) (WrapSing Sing b
s2) = Sing a -> Sing b -> Maybe (a :~: b)
forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Maybe (a :~: b)
decideEquality Sing a
s1 Sing b
s2
decideCoercion :: forall k (a :: k) (b :: k). SDecide k
=> Sing a -> Sing b -> Maybe (Coercion a b)
decideCoercion :: forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Maybe (Coercion a b)
decideCoercion Sing a
a Sing b
b =
case Sing a
a Sing a -> Sing b -> Decision (a :~: b)
forall (a :: k) (b :: k). Sing a -> Sing b -> Decision (a :~: b)
forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Decision (a :~: b)
%~ Sing b
b of
Proved a :~: b
Refl -> Coercion a b -> Maybe (Coercion a b)
forall a. a -> Maybe a
Just Coercion a b
forall {k} (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
Disproved Refuted (a :~: b)
_ -> Maybe (Coercion a b)
forall a. Maybe a
Nothing
instance SDecide k => TestCoercion (WrappedSing :: k -> Type) where
testCoercion :: forall (a :: k) (b :: k).
WrappedSing a -> WrappedSing b -> Maybe (Coercion a b)
testCoercion (WrapSing Sing a
s1) (WrapSing Sing b
s2) = Sing a -> Sing b -> Maybe (Coercion a b)
forall k (a :: k) (b :: k).
SDecide k =>
Sing a -> Sing b -> Maybe (Coercion a b)
decideCoercion Sing a
s1 Sing b
s2