witness-0.5: src/Data/Witness/Cons.hs
module Data.Witness.Cons where
import Data.Constraint
import Data.Countable
import Data.Empty
import Data.Kind
import Data.Proxy
import Data.Searchable
import Data.Type.Equality
import Data.Witness.All
import Data.Witness.Constraint
import Data.Witness.Finite
import Data.Witness.List
import Data.Witness.ListElement
import Data.Witness.Representative
import Prelude
newtype EmptyType t =
MkEmptyType None
deriving (Eq, Countable, Searchable, Empty)
instance Finite (EmptyType t) where
allValues = []
assemble _ = pure never
instance TestEquality EmptyType where
testEquality = never
instance Representative EmptyType where
getRepWitness = never
instance FiniteWitness EmptyType where
assembleWitnessF _ = pure emptyAllF
instance WitnessConstraint c EmptyType where
witnessConstraint = never
emptyAll :: AllValue EmptyType
emptyAll = MkAllValue never
emptyAllF :: AllF EmptyType f
emptyAllF = MkAllF never
data ConsType a r t where
FirstType :: ConsType t r t
RestType :: r t -> ConsType a r t
instance TestEquality r => TestEquality (ConsType a r) where
testEquality FirstType FirstType = return Refl
testEquality (RestType r1) (RestType r2) = do
Refl <- testEquality r1 r2
return Refl
testEquality _ _ = Nothing
instance FiniteWitness r => FiniteWitness (ConsType a r) where
assembleWitnessF getsel =
(\f (MkAllF r) ->
MkAllF $ \wt ->
case wt of
FirstType -> f
RestType rt -> r rt) <$>
getsel FirstType <*>
assembleWitnessF (getsel . RestType)
instance (c a, WitnessConstraint c r) => WitnessConstraint c (ConsType a r) where
witnessConstraint FirstType = Dict
witnessConstraint (RestType rt) =
case witnessConstraint @_ @c rt of
Dict -> Dict
consAll :: a -> AllValue r -> AllValue (ConsType a r)
consAll a (MkAllValue tup) =
MkAllValue $ \esel ->
case esel of
FirstType -> a
RestType sel -> tup sel
class Is (ListType Proxy) (FiniteConsWitness sel) => IsFiniteConsWitness (sel :: k -> Type) where
type FiniteConsWitness sel :: [k]
toLTW :: forall t. sel t -> ListElementType (FiniteConsWitness sel) t
fromLTW :: forall t. ListElementType (FiniteConsWitness sel) t -> sel t
instance Is (ListType Proxy) edits => IsFiniteConsWitness (ListElementType edits) where
type FiniteConsWitness (ListElementType edits) = edits
toLTW = id
fromLTW = id
instance IsFiniteConsWitness EmptyType where
type FiniteConsWitness EmptyType = '[]
toLTW wit = never wit
fromLTW lt = never lt
instance IsFiniteConsWitness lt => IsFiniteConsWitness (ConsType a lt) where
type FiniteConsWitness (ConsType a lt) = a : (FiniteConsWitness lt)
toLTW FirstType = FirstElementType
toLTW (RestType sel) = RestElementType $ toLTW sel
fromLTW FirstElementType = FirstType
fromLTW (RestElementType lt) = RestType $ fromLTW lt