@@ -15,7 +15,7 @@ import Data.Maybe
15import Data.Schematic.Instances ()
15import Data.Schematic.Instances ()
16import Data.Schematic.Utils
16import Data.Schematic.Utils
17import Data.Scientific
17import Data.Scientific
18−import Data.Singletons.Prelude.List
18+import Data.Singletons.Prelude.List hiding (All)
19import Data.Singletons.TH
19import Data.Singletons.TH
20import Data.Singletons.TypeLits
20import Data.Singletons.TypeLits
21import Data.Text as T
21import Data.Text as T
@@ -27,6 +27,10 @@ import Prelude as P
27import Test.SmallCheck.Series
27import Test.SmallCheck.Series
30+type family All (c :: k -> Constraint) (s :: [k]) :: Constraint where
32+ All c (a ': as) = (c a, All c as)
30type family CRepr (s :: Schema) :: Type where
34type family CRepr (s :: Schema) :: Type where
31 CRepr ('SchemaText cs) = TextConstraint
35 CRepr ('SchemaText cs) = TextConstraint
32 CRepr ('SchemaNumber cs) = NumberConstraint
36 CRepr ('SchemaNumber cs) = NumberConstraint
@@ -38,22 +42,27 @@ data TextConstraint
40 | TRegex Symbol
44 | TRegex Symbol
41 deriving (Generic)
46 deriving (Generic)
43data instance Sing (tc :: TextConstraint) where
48data instance Sing (tc :: TextConstraint) where
44− STEq :: Sing n -> Sing ('TEq n)
49+ STEq :: (KnownNat n) => Sing n -> Sing ('TEq n)
45− STLe :: Sing n -> Sing ('TLe n)
50+ STLe :: (KnownNat n) => Sing n -> Sing ('TLe n)
46− STGt :: Sing n -> Sing ('TGt n)
51+ STGt :: (KnownNat n) => Sing n -> Sing ('TGt n)
47− STRegex :: Sing s -> Sing ('TRegex s)
52+ STRegex :: (KnownSymbol s, Known (Sing s)) => Sing s -> Sing ('TRegex s)
48−
53+ STEnum :: (All KnownSymbol ss, Known (Sing ss)) => Sing ss -> Sing ('TEnum ss)
49−instance Known (Sing n) => Known (Sing ('TEq n)) where known = STEq known
55+instance (KnownNat n) => Known (Sing ('TEq n)) where known = STEq known
50−instance Known (Sing n) => Known (Sing ('TGt n)) where known = STGt known
56+instance (KnownNat n) => Known (Sing ('TGt n)) where known = STGt known
51−instance Known (Sing n) => Known (Sing ('TLe n)) where known = STLe known
57+instance (KnownNat n) => Known (Sing ('TLe n)) where known = STLe known
52−instance Known (Sing s) => Known (Sing ('TRegex s)) where known = STRegex known
58+instance (KnownSymbol s, Known (Sing s)) => Known (Sing ('TRegex s)) where known = STRegex known
59+instance (All KnownSymbol ss, Known (Sing ss)) => Known (Sing ('TEnum ss)) where known = STEnum known
54instance Eq (Sing ('TEq n)) where _ == _ = True
61instance Eq (Sing ('TEq n)) where _ == _ = True
55instance Eq (Sing ('TLe n)) where _ == _ = True
62instance Eq (Sing ('TLe n)) where _ == _ = True
56instance Eq (Sing ('TGt n)) where _ == _ = True
63instance Eq (Sing ('TGt n)) where _ == _ = True
64+instance Eq (Sing ('TRegex t)) where _ == _ = True
65+instance Eq (Sing ('TEnum ss)) where _ == _ = True
58data NumberConstraint
67data NumberConstraint
@@ -62,13 +71,13 @@ data NumberConstraint
62 deriving (Generic)
71 deriving (Generic)
64data instance Sing (nc :: NumberConstraint) where
73data instance Sing (nc :: NumberConstraint) where
65− SNEq :: Sing n -> Sing ('NEq n)
74+ SNEq :: KnownNat n => Sing n -> Sing ('NEq n)
66− SNGt :: Sing n -> Sing ('NGt n)
75+ SNGt :: KnownNat n => Sing n -> Sing ('NGt n)
67− SNLe :: Sing n -> Sing ('NLe n)
76+ SNLe :: KnownNat n => Sing n -> Sing ('NLe n)
69−instance Known (Sing n) => Known (Sing ('NEq n)) where known = SNEq known
78+instance KnownNat n => Known (Sing ('NEq n)) where known = SNEq known
70−instance Known (Sing n) => Known (Sing ('NGt n)) where known = SNGt known
79+instance KnownNat n => Known (Sing ('NGt n)) where known = SNGt known
71−instance Known (Sing n) => Known (Sing ('NLe n)) where known = SNLe known
80+instance KnownNat n => Known (Sing ('NLe n)) where known = SNLe known
73instance Eq (Sing ('NEq n)) where _ == _ = True
82instance Eq (Sing ('NEq n)) where _ == _ = True
74instance Eq (Sing ('NLe n)) where _ == _ = True
83instance Eq (Sing ('NLe n)) where _ == _ = True
@@ -79,9 +88,9 @@ data ArrayConstraint
79 deriving (Generic)
88 deriving (Generic)
81data instance Sing (ac :: ArrayConstraint) where
90data instance Sing (ac :: ArrayConstraint) where
82− SAEq :: Sing n -> Sing ('AEq n)
91+ SAEq :: KnownNat n => Sing n -> Sing ('AEq n)
84−instance Known (Sing n) => Known (Sing ('AEq n)) where known = SAEq known
93+instance KnownNat n => Known (Sing ('AEq n)) where known = SAEq known
86instance Eq (Sing ('AEq n)) where _ == _ = True
95instance Eq (Sing ('AEq n)) where _ == _ = True
@@ -123,11 +132,24 @@ instance Eq (Sing ('SchemaObject cs)) where _ == _ = True
123instance Eq (Sing ('SchemaOptional s)) where _ == _ = True
132instance Eq (Sing ('SchemaOptional s)) where _ == _ = True
125data FieldRepr :: (Symbol, Schema) -> Type where
134data FieldRepr :: (Symbol, Schema) -> Type where
136+ :: (Known (Sing schema), KnownSymbol name)
126− FieldRepr :: KnownSymbol name => JsonRepr schema -> FieldRepr '(name, schema)
138+ -> FieldRepr '(name, schema)
128−type family MapSnd (cs :: [(Symbol, Schema)]) :: [Schema] where
140+knownFieldName
129− MapSnd '[] = '[]
141+ :: forall proxy (fieldName :: Symbol) schema
130− MapSnd ( '(fn, schema) ': as) = schema ': MapSnd as
142+ . KnownSymbol fieldName
143+ => proxy '(fieldName, schema)
145+knownFieldName _ = T.pack $ symbolVal (Proxy @fieldName)
148+ :: forall proxy fieldName schema
149+ . Known (Sing schema)
150+ => proxy '(fieldName, schema)
152+knownFieldSchema _ = known
132deriving instance Show (JsonRepr schema) => Show (FieldRepr '(name, schema))
154deriving instance Show (JsonRepr schema) => Show (FieldRepr '(name, schema))
@@ -136,6 +158,7 @@ instance Eq (JsonRepr schema) => Eq (FieldRepr '(name, schema)) where
138 ( KnownSymbol name
160 ( KnownSymbol name
161+ , Known (Sing schema)
139 , Serial m (JsonRepr schema) )
162 , Serial m (JsonRepr schema) )
140 => Serial m (FieldRepr '(name, schema)) where
163 => Serial m (FieldRepr '(name, schema)) where
141 series = FieldRepr <$> series
164 series = FieldRepr <$> series
@@ -269,9 +292,9 @@ instance J.ToJSON (JsonRepr a) where
269 RNil -> []
292 RNil -> []
270 fr@(FieldRepr _) :& tl -> (extract fr) : fold tl
293 fr@(FieldRepr _) :& tl -> (extract fr) : fold tl
272−class FalseConstraint
295+class FalseConstraint a
274−type family TopLevel (spec :: Schema) :: Constraint where
297+type family TopLevel (schema :: Schema) :: Constraint where
275− TopLevel ('SchemaArray a e) = ()
298+ TopLevel ('SchemaArray acs s) = ()
276− TopLevel ('SchemaObject o) = ()
299+ TopLevel ('SchemaObject o) = ()
277− TopLevel spec = FalseConstraint
300+ TopLevel spec = FalseConstraint spec