{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Boring (
Boring (..),
Absurd (..),
vacuous,
boringRep,
untainted,
devoid,
united,
boringYes,
absurdNo,
) where
import Prelude ()
import Prelude.Compat
import Control.Applicative (Const (..))
import Data.Functor.Identity (Identity (..))
import Data.Functor.Compose (Compose (..))
import Data.Functor.Product (Product (..))
import Data.Functor.Sum (Sum (..))
import Data.Functor.Rep (Representable (..))
import Data.Constraint (Dict (..))
import Data.List.NonEmpty (NonEmpty (..))
import Data.Proxy (Proxy (..))
import Data.Tagged (Tagged (..))
import Data.Type.Dec (Dec (..), Decidable (..))
import Data.Stream.Infinite (Stream (..))
import GHC.Generics hiding (Rep)
import qualified Data.Fin as Fin
import qualified Data.Nat as Nat
import qualified Data.Singletons.Bool as Bool
import qualified Data.Type.Nat as Nat
import qualified Data.Type.Nat.LE as ZeroSucc
import qualified Data.Type.Nat.LE.ReflStep as ReflStep
import qualified Data.Vec.Lazy as Vec
import qualified Data.Vec.Pull as Vec.Pull
import qualified Data.Void as V
import qualified Generics.SOP as SOP
#if MIN_VERSION_base(4,7,0)
import qualified Data.Coerce as Co
import qualified Data.Type.Coercion as Co
import qualified Data.Type.Equality as Eq
#endif
class Boring a where
boring :: a
instance Boring () where
boring = ()
instance Boring b => Boring (a -> b) where
boring = const boring
instance Boring (Proxy a) where
boring = Proxy
instance Boring a => Boring (Const a b) where
boring = Const boring
instance Boring b => Boring (Tagged a b) where
boring = Tagged boring
instance Boring a => Boring (Identity a) where
boring = Identity boring
instance Boring a => Boring (SOP.I a) where
boring = SOP.I boring
instance Boring b => Boring (SOP.K b a) where
boring = SOP.K boring
instance Boring (f (g a)) => Boring (Compose f g a) where
boring = Compose boring
instance (Boring (f a), Boring (g a)) => Boring (Product f g a) where
boring = Pair boring boring
instance c => Boring (Dict c) where
boring = Dict
instance (Boring a, Boring b) => Boring (a, b) where
boring = (boring, boring)
instance (Boring a, Boring b, Boring c) => Boring (a, b, c) where
boring = (boring, boring, boring)
instance (Boring a, Boring b, Boring c, Boring d) => Boring (a, b, c, d) where
boring = (boring, boring, boring, boring)
instance (Boring a, Boring b, Boring c, Boring d, Boring e) => Boring (a, b, c, d, e) where
boring = (boring, boring, boring, boring, boring)
instance Boring a => Boring (Stream a) where
boring = boring :> boring
instance Absurd a => Boring [a] where
boring = []
instance Absurd a => Boring (Maybe a) where
boring = Nothing
#if MIN_VERSION_base(4,7,0)
instance Co.Coercible a b => Boring (Co.Coercion a b) where
boring = Co.Coercion
instance a ~ b => Boring (a Eq.:~: b) where
boring = Eq.Refl
# if MIN_VERSION_base(4,12,0)
instance a Eq.~~ b => Boring (a Eq.:~~: b) where
boring = Eq.HRefl
# endif
#endif
instance n ~ 'Nat.Z => Boring (Vec.Vec n a) where
boring = Vec.empty
instance n ~ 'Nat.Z => Boring (Vec.Pull.Vec n a) where
boring = Vec.Pull.empty
instance n ~ ('Nat.S 'Nat.Z) => Boring (Fin.Fin n) where
boring = Fin.boring
instance Nat.SNatI n => Boring (Nat.SNat n) where
boring = Nat.snat
instance Bool.SBoolI b => Boring (Bool.SBool b) where
boring = Bool.sbool
instance ZeroSucc.LE n m => Boring (ZeroSucc.LEProof n m) where
boring = ZeroSucc.leProof
instance (ZeroSucc.LE n m, Nat.SNatI m) => Boring (ReflStep.LEProof n m) where
boring = ReflStep.fromZeroSucc ZeroSucc.leProof
instance Boring (U1 p) where
boring = U1
instance Boring c => Boring (K1 i c p) where
boring = K1 boring
instance Boring (f p) => Boring (M1 i c f p) where
boring = M1 boring
instance (Boring (f p), Boring (g p)) => Boring ((f :*: g) p) where
boring = boring :*: boring
instance Boring p => Boring (Par1 p) where
boring = Par1 boring
instance Boring (f p) => Boring (Rec1 f p) where
boring = Rec1 boring
instance Boring (f (g p)) => Boring ((f :.: g) p) where
boring = Comp1 boring
class Absurd a where
absurd :: a -> b
instance Absurd V.Void where
absurd = V.absurd
instance (Absurd a, Absurd b) => Absurd (Either a b) where
absurd (Left a) = absurd a
absurd (Right b) = absurd b
instance Absurd a => Absurd (NonEmpty a) where
absurd (x :| _) = absurd x
instance Absurd a => Absurd (Stream a) where
absurd (x :> _) = absurd x
instance Absurd a => Absurd (Identity a) where
absurd = absurd . runIdentity
instance Absurd (f (g a)) => Absurd (Compose f g a) where
absurd = absurd . getCompose
instance (Absurd (f a), Absurd (g a)) => Absurd (Sum f g a) where
absurd (InL fa) = absurd fa
absurd (InR ga) = absurd ga
instance Absurd b => Absurd (Const b a) where
absurd = absurd . getConst
instance Absurd a => Absurd (Tagged b a) where
absurd = absurd . unTagged
instance Absurd a => Absurd (SOP.I a) where
absurd = absurd . SOP.unI
instance Absurd b => Absurd (SOP.K b a) where
absurd = absurd . SOP.unK
instance n ~ 'Nat.Z => Absurd (Fin.Fin n) where
absurd = Fin.absurd
instance (ZeroSucc.LE m n, n' ~ 'Nat.S n) => Absurd (ZeroSucc.LEProof n' m) where
absurd = ZeroSucc.leSwap' ZeroSucc.leProof
instance (ZeroSucc.LE m n, n' ~ 'Nat.S n, Nat.SNatI n) => Absurd (ReflStep.LEProof n' m) where
absurd = ZeroSucc.leSwap' ZeroSucc.leProof . ReflStep.toZeroSucc
instance Absurd (V1 p) where
absurd v = case v of {}
instance Absurd c => Absurd (K1 i c p) where
absurd = absurd . unK1
instance Absurd (f p) => Absurd (M1 i c f p) where
absurd = absurd . unM1
instance (Absurd (f p), Absurd (g p)) => Absurd ((f :+: g) p) where
absurd (L1 a) = absurd a
absurd (R1 b) = absurd b
instance Absurd p => Absurd (Par1 p) where
absurd = absurd . unPar1
instance Absurd (f p) => Absurd (Rec1 f p) where
absurd = absurd . unRec1
instance Absurd (f (g p)) => Absurd ((f :.: g) p) where
absurd = absurd . unComp1
vacuous :: (Functor f, Absurd a) => f a -> f b
vacuous = fmap absurd
boringRep :: (Representable f, Absurd (Rep f)) => f a
boringRep = tabulate absurd
untainted :: (Representable f, Boring (Rep f)) => f a -> a
untainted = flip index boring
devoid :: Absurd s => p a (f b) -> s -> f s
devoid _ = absurd
united :: (Boring a, Functor f) => (a -> f a) -> s -> f s
united f v = v <$ f boring
instance Decidable a => Boring (Dec a) where
boring = decide
boringYes :: Boring a => Dec a
boringYes = Yes boring
absurdNo :: Absurd a => Dec a
absurdNo = No absurd