{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
{-# OPTIONS_GHC -Wall #-}
module Data.Exists
(
Exists(..)
, Exists2(..)
, Exists3(..)
, Some(..)
, DependentPair(..)
, WitnessedEquality(..)
, WitnessedOrdering(..)
, ApplyForall(..)
, ApplyForeach(..)
, ApplyLifted(..)
, EqForall(..)
, EqForallPoly(..)
, EqForeach(..)
, OrdForall(..)
, OrdForallPoly(..)
, OrdForeach(..)
, ShowForall(..)
, ShowForeach(..)
, ReadExists(..)
, EnumForall(..)
, EnumExists(..)
, BoundedExists(..)
, SemigroupForall(..)
, SemigroupForeach(..)
, MonoidForall(..)
, MonoidForeach(..)
, HashableForall(..)
, HashableForeach(..)
, PathPieceExists(..)
, FromJSONForeach(..)
, FromJSONExists(..)
, ToJSONForall(..)
, ToJSONForeach(..)
, ToJSONKeyFunctionForall(..)
, FromJSONKeyFunctionForeach(..)
, ToJSONKeyForall(..)
, ToJSONKeyForeach(..)
, FromJSONKeyExists(..)
, FromJSONKeyForeach(..)
, StorableForeach(..)
, StorableForall(..)
, PrimForall(..)
, BinaryExists(..)
, BinaryForeach(..)
, EqForall2(..)
, EqForallPoly2(..)
, ShowForall2(..)
, ShowForeach2(..)
, BinaryExists2(..)
, Sing
, SingList(..)
, SingMaybe(..)
, Reify(..)
, Unreify(..)
, EqSing(..)
, OrdSing(..)
, ShowSing(..)
, ToJSONSing(..)
, FromJSONSing(..)
, ToSing(..)
, SingKind(..)
, showsForall
, showsForeach
, showForall
, showListForall
, showListForeach
, showsForall2
, showForall2
, defaultEqForallPoly
, defaultCompareForallPoly
, parseJSONMapForeachKey
, toJSONMapForeachKey
, weakenEquality
, weakenOrdering
, strengthenEquality
, strengthenOrdering
, strengthenUnequalOrdering
, unreifyList
) where
import Control.Applicative (Const(..))
import Data.Aeson (ToJSON(..),FromJSON(..))
import Data.Aeson (ToJSONKey(..),FromJSONKey(..))
import Data.Aeson (ToJSONKeyFunction(..),FromJSONKeyFunction(..))
import Data.Aeson.Internal ((<?>),JSONPathElement(Key,Index))
import Data.Binary (Get,Put,Binary)
import Data.Binary.Lifted (Binary1(..))
import Data.Coerce (coerce)
import Data.Functor.Classes (Eq1(..),Show1(..),Ord1(..),eq1,compare1)
import Data.Functor.Compose (Compose(..))
import Data.Functor.Product (Product(..))
import Data.Functor.Sum (Sum(..))
import Data.Hashable (Hashable(..))
import Data.Kind (Type)
import Data.Map.Strict (Map)
import Data.Monoid.Lifted (Semigroup1(..),Monoid1(..),append1,empty1)
import Data.Proxy (Proxy(..))
import Data.Semigroup (Semigroup)
import Data.Text (Text)
import Data.Type.Equality ((:~:)(Refl),TestEquality(..))
import Foreign.Ptr (Ptr)
import GHC.Exts (dataToTag#,State#,Int#,Proxy#,Addr#,ByteArray#,MutableByteArray#)
import GHC.Int (Int(..))
import qualified Data.Aeson.Encoding as Aeson
import qualified Data.Aeson.Encoding.Internal as AEI
import qualified Data.Aeson.Types as Aeson
import qualified Data.Binary as BN
import qualified Data.HashMap.Strict as HM
import qualified Data.Map.Strict as M
import qualified Data.Semigroup as SG
import qualified Data.Traversable as TRV
import qualified Data.Vector as V
import qualified Text.Read as R
import qualified Web.PathPieces as PP
data Exists (f :: k -> Type) = forall a. Exists !(f a)
data Exists2 (f :: k -> j -> Type) = forall a b. Exists2 !(f a b)
data Exists3 (f :: k -> j -> l -> Type) = forall a b c. Exists3 !(f a b c)
data DependentPair (f :: k -> Type) (g :: k -> Type) =
forall a. DependentPair (f a) (g a)
data Some (f :: k -> Type) = forall a. Some !(Sing a) !(f a)
data WitnessedEquality (a :: k) (b :: k) where
WitnessedEqualityEqual :: WitnessedEquality a a
WitnessedEqualityUnequal :: WitnessedEquality a b
data WitnessedOrdering (a :: k) (b :: k) where
WitnessedOrderingLT :: WitnessedOrdering a b
WitnessedOrderingEQ :: WitnessedOrdering a a
WitnessedOrderingGT :: WitnessedOrdering a b
data ToJSONKeyFunctionForall f
= ToJSONKeyTextForall !(forall a. f a -> Text) !(forall a. f a -> Aeson.Encoding' Text)
| ToJSONKeyValueForall !(forall a. f a -> Aeson.Value) !(forall a. f a -> Aeson.Encoding)
data FromJSONKeyFunctionForeach f
= FromJSONKeyTextParserForeach !(forall a. Sing a -> Text -> Aeson.Parser (f a))
| FromJSONKeyValueForeach !(forall a. Sing a -> Aeson.Value -> Aeson.Parser (f a))
newtype ApplyForall f a = ApplyForall { getApplyForall :: f a }
instance ShowForall f => Show (ApplyForall f a) where
showsPrec p (ApplyForall x) = showParen (p > 10)
$ showString "ApplyForall "
. showsPrecForall 11 x
instance SemigroupForall f => Semigroup (ApplyForall f a) where
(<>) = appendForall
instance MonoidForall f => Monoid (ApplyForall f a) where
mempty = emptyForall
mappend = (SG.<>)
instance SemigroupForall f => SemigroupForall (ApplyForall f) where
appendForall (ApplyForall a) (ApplyForall b) = ApplyForall (appendForall a b)
instance MonoidForall f => MonoidForall (ApplyForall f) where
emptyForall = ApplyForall emptyForall
newtype ApplyLifted f a = ApplyLifted { getApplyLifted :: f a }
instance (Semigroup1 f, Semigroup a) => Semigroup (ApplyLifted f a) where
(<>) = append1
instance (Monoid1 f, Monoid a) => Monoid (ApplyLifted f a) where
mempty = empty1
mappend = liftAppend mappend
instance (Eq1 f, Eq a) => Eq (ApplyLifted f a) where
(==) = eq1
instance (Ord1 f, Ord a) => Ord (ApplyLifted f a) where
compare = compare1
instance Semigroup1 f => Semigroup1 (ApplyLifted f) where
liftAppend g (ApplyLifted a) (ApplyLifted b) = ApplyLifted (liftAppend g a b)
instance Monoid1 f => Monoid1 (ApplyLifted f) where
liftEmpty f = ApplyLifted (liftEmpty f)
instance Eq1 f => Eq1 (ApplyLifted f) where
liftEq f (ApplyLifted a) (ApplyLifted b) = liftEq f a b
instance Ord1 f => Ord1 (ApplyLifted f) where
liftCompare f (ApplyLifted a) (ApplyLifted b) = liftCompare f a b
newtype ApplyForeach f a = ApplyForeach { getApplyForeach :: f a }
instance (EqForeach f, Reify a) => Eq (ApplyForeach f a) where
ApplyForeach a == ApplyForeach b = eqForeach reify a b
instance (OrdForeach f, Reify a) => Ord (ApplyForeach f a) where
compare (ApplyForeach a) (ApplyForeach b) = compareForeach reify a b
instance (ShowForeach f, Reify a) => Show (ApplyForeach f a) where
showsPrec p (ApplyForeach a) = showParen (p > 10)
$ showString "ApplyForeach "
. showsPrecForeach reify 11 a
instance (SemigroupForeach f, Reify a) => Semigroup (ApplyForeach f a) where
(<>) = appendForeach reify
instance (MonoidForeach f, Reify a) => Monoid (ApplyForeach f a) where
mempty = emptyForeach reify
mappend = (SG.<>)
instance (ToJSONForeach f, Reify a) => ToJSON (ApplyForeach f a) where
toJSON = toJSONForeach reify
instance (FromJSONForeach f, Reify a) => FromJSON (ApplyForeach f a) where
parseJSON = parseJSONForeach reify
instance EqForeach f => EqForeach (ApplyForeach f) where
eqForeach s (ApplyForeach a) (ApplyForeach b) = eqForeach s a b
instance OrdForeach f => OrdForeach (ApplyForeach f) where
compareForeach s (ApplyForeach a) (ApplyForeach b) = compareForeach s a b
instance SemigroupForeach f => SemigroupForeach (ApplyForeach f) where
appendForeach s (ApplyForeach a) (ApplyForeach b) = ApplyForeach (appendForeach s a b)
instance MonoidForeach f => MonoidForeach (ApplyForeach f) where
emptyForeach s = ApplyForeach (emptyForeach s)
instance ToJSONForeach f => ToJSONForeach (ApplyForeach f) where
toJSONForeach s (ApplyForeach x) = toJSONForeach s x
instance FromJSONForeach f => FromJSONForeach (ApplyForeach f) where
parseJSONForeach s = fmap ApplyForeach . parseJSONForeach s
instance ToJSONKeyForeach f => ToJSONKeyForeach (ApplyForeach f) where
toJSONKeyForeach = case toJSONKeyForeach of
ToJSONKeyTextForall f g -> ToJSONKeyTextForall
(\(Pair s (ApplyForeach x)) -> f (Pair s x))
(\(Pair s (ApplyForeach x)) -> g (Pair s x))
ToJSONKeyValueForall f g -> ToJSONKeyValueForall
(\(Pair s (ApplyForeach x)) -> f (Pair s x))
(\(Pair s (ApplyForeach x)) -> g (Pair s x))
instance FromJSONKeyForeach f => FromJSONKeyForeach (ApplyForeach f) where
fromJSONKeyForeach = case fromJSONKeyForeach of
FromJSONKeyTextParserForeach f -> FromJSONKeyTextParserForeach (\s t -> fmap ApplyForeach (f s t))
FromJSONKeyValueForeach f -> FromJSONKeyValueForeach (\s t -> fmap ApplyForeach (f s t))
instance (ToJSONKeyForeach f, Reify a) => ToJSONKey (ApplyForeach f a) where
toJSONKey = case toJSONKeyForeach of
ToJSONKeyTextForall toText toEnc -> ToJSONKeyText
(\(ApplyForeach x) -> toText (Pair reify x))
(\(ApplyForeach x) -> toEnc (Pair reify x))
ToJSONKeyValueForall toValue toEnc -> ToJSONKeyValue
(\(ApplyForeach x) -> toValue (Pair reify x))
(\(ApplyForeach x) -> toEnc (Pair reify x))
toJSONKeyList = case toJSONKeyForeach of
ToJSONKeyTextForall toText toEnc -> ToJSONKeyValue
(\xs -> toJSON $ map (\(ApplyForeach x) -> toText (Pair reify x)) xs)
(\xs -> Aeson.list (textEncodingToValueEncoding . toEnc . Pair reify) (map getApplyForeach xs))
ToJSONKeyValueForall toValue toEnc -> ToJSONKeyValue
(\xs -> toJSON $ map (\(ApplyForeach x) -> toValue (Pair reify x)) xs)
(\xs -> Aeson.list (toEnc . Pair reify) (map getApplyForeach xs))
textEncodingToValueEncoding :: Aeson.Encoding' Text -> Aeson.Encoding' Aeson.Value
textEncodingToValueEncoding = AEI.retagEncoding
instance (FromJSONKeyForeach f, Reify a) => FromJSONKey (ApplyForeach f a) where
fromJSONKey = case fromJSONKeyForeach of
FromJSONKeyTextParserForeach f -> FromJSONKeyTextParser (fmap ApplyForeach . f reify)
FromJSONKeyValueForeach f -> FromJSONKeyValue (fmap ApplyForeach . f reify)
fromJSONKeyList = case fromJSONKeyForeach of
FromJSONKeyTextParserForeach f -> FromJSONKeyValue $ Aeson.withArray "ApplyForeach" $ \xs -> do
fmap V.toList (mapM (fmap ApplyForeach . Aeson.withText "ApplyForeach" (f reify)) xs)
FromJSONKeyValueForeach f -> FromJSONKeyValue $ Aeson.withArray "ApplyForeach" $ \xs -> do
fmap V.toList (mapM (fmap ApplyForeach . f reify) xs)
class EqForall f where
eqForall :: f a -> f a -> Bool
class EqForeach f where
eqForeach :: Sing a -> f a -> f a -> Bool
class EqForall f => OrdForall f where
compareForall :: f a -> f a -> Ordering
class EqForall f => EqForallPoly f where
eqForallPoly :: f a -> f b -> WitnessedEquality a b
default eqForallPoly :: TestEquality f => f a -> f b -> WitnessedEquality a b
eqForallPoly = defaultEqForallPoly
class (OrdForall f, EqForallPoly f) => OrdForallPoly f where
compareForallPoly :: f a -> f b -> WitnessedOrdering a b
class EqForeach f => OrdForeach f where
compareForeach :: Sing a -> f a -> f a -> Ordering
class ShowForall f where
showsPrecForall :: Int -> f a -> ShowS
class ShowForeach f where
showsPrecForeach :: Sing a -> Int -> f a -> ShowS
class ShowForall2 f where
showsPrecForall2 :: Int -> f a b -> ShowS
class ShowForeach2 f where
showsPrecForeach2 :: Sing a -> Sing b -> Int -> f a b -> ShowS
showsForall :: ShowForall f => f a -> ShowS
showsForall = showsPrecForall 0
showsForeach :: ShowForeach f => Sing a -> f a -> ShowS
showsForeach s = showsPrecForeach s 0
showForall :: ShowForall f => f a -> String
showForall x = showsForall x ""
showsForall2 :: ShowForall2 f => f a b -> ShowS
showsForall2 = showsPrecForall2 0
showForall2 :: ShowForall2 f => f a b -> String
showForall2 x = showsForall2 x ""
class ReadExists f where
readPrecExists :: R.ReadPrec (Exists f)
class EqForall2 f where
eqForall2 :: f a b -> f a b -> Bool
class EqForallPoly2 (f :: k -> j -> Type) where
eqForallPoly2 :: forall (a :: k) (b :: j) (c :: k) (d :: j). f a b -> f c d -> WitnessedEquality '(a,b) '(c,d)
class HashableForall f where
hashWithSaltForall :: Int -> f a -> Int
class HashableForeach f where
hashWithSaltForeach :: Sing a -> Int -> f a -> Int
class ToJSONKeyForall f where
toJSONKeyForall :: ToJSONKeyFunctionForall f
class ToJSONKeyForeach f where
toJSONKeyForeach :: ToJSONKeyFunctionForall (Product Sing f)
class FromJSONKeyExists f where
fromJSONKeyExists :: FromJSONKeyFunction (Exists f)
class FromJSONKeyForeach f where
fromJSONKeyForeach :: FromJSONKeyFunctionForeach f
class ToJSONForall f where
toJSONForall :: f a -> Aeson.Value
class ToJSONForeach f where
toJSONForeach :: Sing a -> f a -> Aeson.Value
class FromJSONForeach f where
parseJSONForeach :: Sing a -> Aeson.Value -> Aeson.Parser (f a)
class FromJSONExists f where
parseJSONExists :: Aeson.Value -> Aeson.Parser (Exists f)
class EnumForall f where
toEnumForall :: Int -> f a
fromEnumForall :: f a -> Int
class EnumExists f where
toEnumExists :: Int -> Exists f
fromEnumExists :: Exists f -> Int
class BoundedExists f where
minBoundExists :: Exists f
maxBoundExists :: Exists f
class PathPieceExists f where
fromPathPieceForall :: Text -> Maybe (Exists f)
toPathPieceForall :: Exists f -> Text
class SemigroupForeach f where
appendForeach :: Sing a -> f a -> f a -> f a
class SemigroupForall f where
appendForall :: f a -> f a -> f a
class StorableForeach (f :: k -> Type) where
peekForeach :: Sing a -> Ptr (f a) -> IO (f a)
pokeForeach :: Sing a -> Ptr (f a) -> f a -> IO ()
sizeOfForeach :: forall (a :: k). Proxy f -> Sing a -> Int
class StorableForall (f :: k -> Type) where
peekForall :: Ptr (f a) -> IO (f a)
pokeForall :: Ptr (f a) -> f a -> IO ()
sizeOfForall :: Proxy f -> Int
class PrimForall (f :: k -> Type) where
sizeOfForall# :: Proxy# f -> Int#
alignmentForall# :: Proxy# f -> Int#
indexByteArrayForall# :: ByteArray# -> Int# -> f a
readByteArrayForall# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, f a #)
writeByteArrayForall# :: MutableByteArray# s -> Int# -> f a -> State# s -> State# s
setByteArrayForall# :: MutableByteArray# s -> Int# -> Int# -> f a -> State# s -> State# s
indexOffAddrForall# :: Addr# -> Int# -> f a
readOffAddrForall# :: Addr# -> Int# -> State# s -> (# State# s, f a #)
writeOffAddrForall# :: Addr# -> Int# -> f a -> State# s -> State# s
setOffAddrForall# :: Addr# -> Int# -> Int# -> f a -> State# s -> State# s
class BinaryForeach (f :: k -> Type) where
putForeach :: Sing a -> f a -> Put
getForeach :: Sing a -> Get (f a)
class BinaryExists (f :: k -> Type) where
putExists :: Exists f -> Put
getExists :: Get (Exists f)
class BinaryExists2 (f :: k -> j -> Type) where
putExists2 :: Exists2 f -> Put
getExists2 :: Get (Exists2 f)
instance EqForall Proxy where
eqForall _ _ = True
instance OrdForall Proxy where
compareForall _ _ = EQ
instance ShowForall Proxy where
showsPrecForall = showsPrec
instance ReadExists Proxy where
readPrecExists = fmap Exists R.readPrec
instance SemigroupForall Proxy where
appendForall _ _ = Proxy
instance EqForall ((:~:) a) where
eqForall Refl Refl = True
instance EqForall2 (:~:) where
eqForall2 Refl Refl = True
instance Show a => ShowForall (Const a) where
showsPrecForall p (Const a) = showParen (p > 10)
$ showString "Const "
. showsPrec p a
instance Eq a => EqForall (Const a) where
eqForall (Const x) (Const y) = x == y
instance Ord a => OrdForall (Const a) where
compareForall (Const x) (Const y) = compare x y
instance Hashable a => HashableForall (Const a) where
hashWithSaltForall s (Const a) = hashWithSalt s a
instance FromJSON a => FromJSONForeach (Const a) where
parseJSONForeach _ = fmap Const . parseJSON
instance (ToJSONKeyForall f, ToJSONForall f) => ToJSONKey (Exists f) where
toJSONKey = case toJSONKeyForall of
ToJSONKeyTextForall t e -> ToJSONKeyText (\(Exists a) -> t a) (\(Exists a) -> e a)
ToJSONKeyValueForall v e -> ToJSONKeyValue (\x -> case x of Exists a -> v a) (\(Exists a) -> e a)
instance (FromJSONKeyExists f, FromJSONExists f) => FromJSONKey (Exists f) where
fromJSONKey = fromJSONKeyExists
instance EqForallPoly f => Eq (Exists f) where
Exists a == Exists b = weakenEquality (eqForallPoly a b)
instance EqForallPoly2 f => Eq (Exists2 f) where
Exists2 a == Exists2 b = weakenEquality (eqForallPoly2 a b)
instance OrdForallPoly f => Ord (Exists f) where
compare (Exists a) (Exists b) = weakenOrdering (compareForallPoly a b)
instance HashableForall f => Hashable (Exists f) where
hashWithSalt s (Exists a) = hashWithSaltForall s a
instance ToJSONForall f => ToJSON (Exists f) where
toJSON (Exists a) = toJSONForall a
instance FromJSONExists f => FromJSON (Exists f) where
parseJSON v = parseJSONExists v
instance ShowForall f => Show (Exists f) where
showsPrec p (Exists a) = showParen
(p >= 11)
(showString "Exists " . showsPrecForall 11 a)
instance ShowForall2 f => Show (Exists2 f) where
showsPrec p (Exists2 a) = showParen
(p >= 11)
(showString "Exists " . showsPrecForall2 11 a)
instance ReadExists f => Read (Exists f) where
readPrec = R.parens $ R.prec 10 $ do
R.Ident "Exists" <- R.lexP
R.step readPrecExists
instance EnumExists f => Enum (Exists f) where
fromEnum = fromEnumExists
toEnum = toEnumExists
instance BoundedExists f => Bounded (Exists f) where
minBound = minBoundExists
maxBound = maxBoundExists
instance BinaryExists f => Binary (Exists f) where
get = getExists
put = putExists
instance BinaryExists2 f => Binary (Exists2 f) where
get = getExists2
put = putExists2
instance PathPieceExists f => PP.PathPiece (Exists f) where
toPathPiece = toPathPieceForall
fromPathPiece = fromPathPieceForall
instance (EqForall f, EqForall g) => EqForall (Product f g) where
eqForall (Pair f1 g1) (Pair f2 g2) = eqForall f1 f2 && eqForall g1 g2
instance (EqForallPoly f, EqForallPoly g) => EqForallPoly (Product f g) where
eqForallPoly (Pair f1 g1) (Pair f2 g2) = case eqForallPoly f1 f2 of
WitnessedEqualityEqual -> eqForallPoly g1 g2
WitnessedEqualityUnequal -> WitnessedEqualityUnequal
instance (OrdForall f, OrdForall g) => OrdForall (Product f g) where
compareForall (Pair f1 g1) (Pair f2 g2) = mappend (compareForall f1 f2) (compareForall g1 g2)
instance (OrdForallPoly f, OrdForallPoly g) => OrdForallPoly (Product f g) where
compareForallPoly (Pair f1 g1) (Pair f2 g2) = case compareForallPoly f1 f2 of
WitnessedOrderingLT -> WitnessedOrderingLT
WitnessedOrderingGT -> WitnessedOrderingGT
WitnessedOrderingEQ -> compareForallPoly g1 g2
instance (ShowForall f, ShowForall g) => ShowForall (Product f g) where
showsPrecForall p (Pair f g) = showParen
(p >= 11)
(showString "Pair " . showsPrecForall 11 f . showChar ' ' . showsPrecForall 11 g)
instance (Semigroup1 f, SemigroupForall g) => SemigroupForall (Compose f g) where
appendForall (Compose x) (Compose y) = Compose (liftAppend appendForall x y)
instance (Aeson.ToJSON1 f, ToJSONForall g) => ToJSONForall (Compose f g) where
toJSONForall (Compose x) = Aeson.liftToJSON toJSONForall (Aeson.toJSON . map toJSONForall) x
instance (Aeson.ToJSON1 f, ToJSONForeach g) => ToJSONForeach (Compose f g) where
toJSONForeach s (Compose x) = Aeson.liftToJSON (toJSONForeach s) (Aeson.toJSON . map (toJSONForeach s)) x
instance (Aeson.FromJSON1 f, FromJSONForeach g) => FromJSONForeach (Compose f g) where
parseJSONForeach s = fmap Compose . Aeson.liftParseJSON
(parseJSONForeach s)
(Aeson.withArray "Compose" (fmap V.toList . V.mapM (parseJSONForeach s)))
instance (Eq1 f, EqForall g) => EqForall (Compose f g) where
eqForall (Compose x) (Compose y) = liftEq eqForall x y
instance (Eq1 f, EqForeach g) => EqForeach (Compose f g) where
eqForeach s (Compose x) (Compose y) = liftEq (eqForeach s) x y
instance (Show1 f, ShowForall g) => ShowForall (Compose f g) where
showsPrecForall p (Compose x) = showParen (p > 10) $ showString "Compose " . liftShowsPrec showsPrecForall showListForall 11 x
instance (Show1 f, ShowForeach g) => ShowForeach (Compose f g) where
showsPrecForeach s p (Compose x) = showParen (p > 10) $ showString "Compose " . liftShowsPrec (showsPrecForeach s) (showListForeach s) 11 x
instance (Semigroup1 f, SemigroupForeach g) => SemigroupForeach (Compose f g) where
appendForeach s (Compose x) (Compose y) = Compose (liftAppend (appendForeach s) x y)
instance (Binary1 f, BinaryForeach g) => BinaryForeach (Compose f g) where
putForeach s (Compose x) = liftPut (putForeach s) x
getForeach s = fmap Compose (liftGet (getForeach s))
showListForall :: ShowForall f => [f a] -> ShowS
showListForall = showList__ showsForall
showListForeach :: ShowForeach f => Sing a -> [f a] -> ShowS
showListForeach s = showList__ (showsForeach s)
showList__ :: (a -> ShowS) -> [a] -> ShowS
showList__ _ [] s = "[]" ++ s
showList__ showx (x:xs) s = '[' : showx x (showl xs)
where
showl [] = ']' : s
showl (y:ys) = ',' : showx y (showl ys)
instance (EqForall f, EqForall g) => EqForall (Sum f g) where
eqForall (InL f1) (InL f2) = eqForall f1 f2
eqForall (InR f1) (InR f2) = eqForall f1 f2
eqForall (InR _) (InL _) = False
eqForall (InL _) (InR _) = False
instance (OrdForall f, OrdForall g) => OrdForall (Sum f g) where
compareForall (InL f1) (InL f2) = compareForall f1 f2
compareForall (InR f1) (InR f2) = compareForall f1 f2
compareForall (InR _) (InL _) = GT
compareForall (InL _) (InR _) = LT
defaultCompareForallPoly :: (TestEquality f, OrdForall f) => f a -> f b -> Ordering
defaultCompareForallPoly a b = case testEquality a b of
Nothing -> compare (getTagBox a) (getTagBox b)
Just Refl -> compareForall a b
defaultEqForallPoly :: (TestEquality f, EqForall f) => f a -> f b -> WitnessedEquality a b
defaultEqForallPoly x y = case testEquality x y of
Nothing -> WitnessedEqualityUnequal
Just Refl -> if eqForall x y then WitnessedEqualityEqual else WitnessedEqualityUnequal
getTagBox :: a -> Int
getTagBox !x = I# (dataToTag# x)
{-# INLINE getTagBox #-}
type family Sing = (r :: k -> Type) | r -> k
class SingKind k where
demoteSing :: Sing (a :: k) -> k
promoteSing :: k -> Exists (Sing :: k -> Type)
instance SingKind k => SingKind [k] where
demoteSing SingListNil = []
demoteSing (SingListCons s ss) = demoteSing s : demoteSing ss
promoteSing [] = Exists SingListNil
promoteSing (x : xs) = case promoteSing x of
Exists s -> case promoteSing xs of
Exists ss -> Exists (SingListCons s ss)
type instance Sing = SingList
type instance Sing = SingMaybe
class Unreify k where
unreify :: forall (a :: k) b. Sing a -> (Reify a => b) -> b
instance Unreify k => Unreify [k] where
unreify = unreifyList
class Reify a where
reify :: Sing a
instance Reify '[] where
reify = SingListNil
instance (Reify a, Reify as) => Reify (a ': as) where
reify = SingListCons reify reify
instance Reify 'Nothing where
reify = SingMaybeNothing
instance Reify a => Reify ('Just a) where
reify = SingMaybeJust reify
class EqSing k where
eqSing :: forall (a :: k) (b :: k). Sing a -> Sing b -> Maybe (a :~: b)
class EqSing k => OrdSing k where
compareSing :: forall (a :: k) (b :: k). Sing a -> Sing b -> WitnessedOrdering a b
class ShowSing k where
showsPrecSing :: forall (a :: k). Int -> Sing a -> ShowS
instance EqSing a => EqSing [a] where
eqSing = eqSingList
eqSingList :: forall (a :: [k]) (b :: [k]). EqSing k => SingList a -> SingList b -> Maybe (a :~: b)
eqSingList SingListNil SingListNil = Just Refl
eqSingList SingListNil (SingListCons _ _) = Nothing
eqSingList (SingListCons _ _) SingListNil = Nothing
eqSingList (SingListCons a as) (SingListCons b bs) = case eqSing a b of
Just Refl -> case eqSingList as bs of
Just Refl -> Just Refl
Nothing -> Nothing
Nothing -> Nothing
class SemigroupForeach f => MonoidForeach f where
emptyForeach :: Sing a -> f a
class SemigroupForall f => MonoidForall f where
emptyForall :: f a
data SingList :: forall (k :: Type). [k] -> Type where
SingListNil :: SingList '[]
SingListCons :: Sing r -> SingList rs -> SingList (r ': rs)
instance EqForall SingList where
eqForall _ _ = True
instance EqSing k => EqForallPoly (SingList :: [k] -> Type) where
eqForallPoly SingListNil SingListNil = WitnessedEqualityEqual
eqForallPoly SingListNil (SingListCons _ _) = WitnessedEqualityUnequal
eqForallPoly (SingListCons _ _) SingListNil = WitnessedEqualityUnequal
eqForallPoly (SingListCons r rs) (SingListCons s ss) = case eqSing r s of
Nothing -> WitnessedEqualityUnequal
Just Refl -> case eqForallPoly rs ss of
WitnessedEqualityUnequal -> WitnessedEqualityUnequal
WitnessedEqualityEqual -> WitnessedEqualityEqual
instance (SingKind k, Binary k) => BinaryExists (SingList :: [k] -> Type) where
putExists (Exists xs) = BN.put (demoteSing xs)
getExists = fmap promoteSing BN.get
instance (ShowSing k) => Show (SingList (xs :: [k])) where
showsPrec _ SingListNil = showString "SingListNil"
showsPrec p (SingListCons s ss) = showParen (p > 10)
$ showString "SingListCons "
. showsPrecSing 11 s
. showChar ' '
. showsPrec 11 ss
instance ShowSing k => ShowSing [k] where
showsPrecSing = showsPrec
data SingMaybe :: Maybe k -> Type where
SingMaybeJust :: Sing a -> SingMaybe ('Just a)
SingMaybeNothing :: SingMaybe 'Nothing
unreifyList :: forall (as :: [k]) b. Unreify k
=> SingList as
-> (Reify as => b)
-> b
unreifyList SingListNil b = b
unreifyList (SingListCons s ss) b = unreify s (unreifyList ss b)
instance (EqForeach f, EqSing k) => Eq (Some (f :: k -> Type)) where
Some s1 v1 == Some s2 v2 = case eqSing s1 s2 of
Just Refl -> eqForeach s1 v1 v2
Nothing -> False
instance (OrdForeach f, OrdSing k) => Ord (Some (f :: k -> Type)) where
compare (Some s1 v1) (Some s2 v2) = case compareSing s1 s2 of
WitnessedOrderingEQ -> compareForeach s1 v1 v2
WitnessedOrderingLT -> LT
WitnessedOrderingGT -> GT
instance (ShowForeach f, ShowSing k) => Show (Some (f :: k -> Type)) where
showsPrec p (Some s a) = showParen (p >= 11)
$ showString "Sing "
. showsPrecSing 11 s
. showChar ' '
. showsPrecForeach s 11 a
class ToSing (f :: k -> Type) where
toSing :: f a -> Sing a
class ToJSONSing k where
toJSONSing :: forall (a :: k). Sing a -> Aeson.Value
instance (ToJSONForeach f, ToJSONSing k) => ToJSON (Some (f :: k -> Type)) where
toJSON (Some s v) = toJSON [toJSONSing s, toJSONForeach s v]
class FromJSONSing k where
parseJSONSing :: Aeson.Value -> Aeson.Parser (Exists (Sing :: k -> Type))
instance (FromJSONForeach f, FromJSONSing k) => FromJSON (Some (f :: k -> Type)) where
parseJSON = Aeson.withArray "Some" $ \v -> if V.length v == 2
then do
let x = V.unsafeIndex v 0
y = V.unsafeIndex v 1
Exists s <- parseJSONSing x :: Aeson.Parser (Exists (Sing :: k -> Type))
val <- parseJSONForeach s y
return (Some s val)
else fail "array of length 2 expected"
toJSONMapForeachKey :: (ToJSONKeyForeach f, ToJSONForeach v)
=> Sing a
-> Map (f a) (v a)
-> Aeson.Value
toJSONMapForeachKey s m = case toJSONKeyForeach of
ToJSONKeyTextForall keyToText _ -> toJSON $ M.foldlWithKey'
( \hm key val -> HM.insert (keyToText (Pair s key)) (toJSONForeach s val) hm
) HM.empty m
ToJSONKeyValueForall keyToValue _ -> toJSON $ M.foldrWithKey'
( \key val xs -> (keyToValue (Pair s key), toJSONForeach s val) : xs
) [] m
parseJSONMapForeachKey :: forall k (f :: k -> Type) (a :: k) v. (FromJSONKeyForeach f, OrdForeach f, Unreify k)
=> (Aeson.Value -> Aeson.Parser v)
-> Sing a
-> Aeson.Value
-> Aeson.Parser (Map (f a) v)
parseJSONMapForeachKey valueParser s obj = unreify s $ case fromJSONKeyForeach of
FromJSONKeyTextParserForeach f -> Aeson.withObject "Map k v"
( fmap (M.mapKeysMonotonic getApplyForeach) . HM.foldrWithKey
(\k v m -> M.insert
<$> (coerce (f s k :: Aeson.Parser (f a)) :: Aeson.Parser (ApplyForeach f a)) <?> Key k
<*> valueParser v <?> Key k
<*> m
) (pure M.empty)
) obj
FromJSONKeyValueForeach f -> Aeson.withArray "Map k v"
( fmap (M.mapKeysMonotonic getApplyForeach . M.fromList)
. (coerce :: Aeson.Parser [(f a, v)] -> Aeson.Parser [(ApplyForeach f a, v)])
. TRV.sequence
. zipWith (parseIndexedJSONPair (f s) valueParser) [0..]
. V.toList
) obj
parseIndexedJSONPair :: (Aeson.Value -> Aeson.Parser a) -> (Aeson.Value -> Aeson.Parser b) -> Int -> Aeson.Value -> Aeson.Parser (a, b)
parseIndexedJSONPair keyParser valParser idx value = p value <?> Index idx
where
p = Aeson.withArray "(k,v)" $ \ab ->
let n = V.length ab
in if n == 2
then (,) <$> parseJSONElemAtIndex keyParser 0 ab
<*> parseJSONElemAtIndex valParser 1 ab
else fail $ "cannot unpack array of length " ++
show n ++ " into a pair"
{-# INLINE parseIndexedJSONPair #-}
parseJSONElemAtIndex :: (Aeson.Value -> Aeson.Parser a) -> Int -> V.Vector Aeson.Value -> Aeson.Parser a
parseJSONElemAtIndex p idx ary = p (V.unsafeIndex ary idx) <?> Index idx
weakenEquality :: WitnessedEquality a b -> Bool
weakenEquality = \case
WitnessedEqualityEqual -> True
WitnessedEqualityUnequal -> False
weakenOrdering :: WitnessedOrdering a b -> Ordering
weakenOrdering = \case
WitnessedOrderingGT -> GT
WitnessedOrderingEQ -> EQ
WitnessedOrderingLT -> LT
strengthenEquality :: Bool -> WitnessedEquality a a
strengthenEquality = \case
True -> WitnessedEqualityEqual
False -> WitnessedEqualityUnequal
strengthenOrdering :: Ordering -> WitnessedOrdering a a
strengthenOrdering = \case
LT -> WitnessedOrderingLT
EQ -> WitnessedOrderingEQ
GT -> WitnessedOrderingGT
strengthenUnequalOrdering :: Ordering -> WitnessedOrdering a b
strengthenUnequalOrdering = \case
LT -> WitnessedOrderingLT
EQ -> WitnessedOrderingLT
GT -> WitnessedOrderingGT
instance (EqForallPoly f, ToSing f, EqForeach g) => Eq (DependentPair f g) where
DependentPair a1 b1 == DependentPair a2 b2 = case eqForallPoly a1 a2 of
WitnessedEqualityUnequal -> False
WitnessedEqualityEqual -> eqForeach (toSing a1) b1 b2
instance (OrdForallPoly f, ToSing f, OrdForeach g) => Ord (DependentPair f g) where
compare (DependentPair a1 b1) (DependentPair a2 b2) = case compareForallPoly a1 a2 of
WitnessedOrderingLT -> LT
WitnessedOrderingGT -> GT
WitnessedOrderingEQ -> compareForeach (toSing a1) b1 b2
instance (ShowForall f, ToSing f, ShowForeach g) => Show (DependentPair f g) where
showsPrec p (DependentPair a b) s = showParen
(p >= 11)
(showString "DependentPair " . showsPrecForall 11 a . showChar ' ' . showsPrecForeach (toSing a) 11 b)
s
instance Semigroup a => SemigroupForall (Const a) where
appendForall (Const x) (Const y) = Const (x SG.<> y)
#if MIN_VERSION_base(4,11,0)
instance Monoid a => MonoidForall (Const a) where
#else
instance (Semigroup a, Monoid a) => MonoidForall (Const a) where
#endif
emptyForall = Const mempty