@@ -0,0 +1,94 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2+{-# LANGUAGE InstanceSigs #-}
3+{-# LANGUAGE UndecidableInstances #-}
5+module Data.Schematic.Schema where
7+import Data.Functor.Foldable
8+import Data.Singletons.TH
9+import Data.Kind hiding (Type)
11+import Data.Type.Equality
13+import Data.Vinyl.Functor
14+import GHC.TypeLits (KnownNat, natVal, KnownSymbol, symbolVal, Symbol, Nat)
26+type family CRepr (ty :: k) :: Type
28+type family Repr (ty :: k1) :: k2 where
29+ Repr 'Text = String -- because of matchRegex
30+ Repr 'Number = Double
32+class Constrained c ty | c -> ty where
33+ predicate :: Repr ty -> Bool
37+instance KnownNat nat => Constrained (LengthEqNat nat) Text where
38+ predicate n = natVal (Proxy @nat) == fromIntegral (length n)
40+type instance CRepr (LengthEqNat nat) = Number
42+type family Verifiable (els :: k) (t :: z) :: Constraint where
43+ Verifiable '[] ty = ()
44+ Verifiable (e : els) ty = (Constrained e (CRepr e), Verifiable els ty)
47+ Exists :: f a -> Exists f
50+ forall els ty. Verifiable els ty => C (Rec Proxy els)
54+ SchemaNumber :: Schema
55+ SchemaObjCons :: KnownSymbol label
57+ -> Schema -- new elem
60+ SchemaObjNil :: Schema
62+class Schematic ty where
63+ rep :: Proxy ty -> Schema
65+-- | Signals it's appropriate as a top-level json type
66+-- class Schematic ty => TopLevel ty
70+instance Schematic s => Schematic (c :% s) where
71+ rep _ = rep $ Proxy @s
75+instance Schematic NilObj where
78+data (:**) (label :: Symbol) e (s :: Type)
80+instance (KnownSymbol label, Schematic e, Schematic s)
81+ => Schematic (label :** e s) where
82+ rep _ = SchemaObjCons
89+instance Schematic JText where
93+-- = "carrier" (JString :% LengthEqNat 2 :% Regexp "[a-zA-Z]+")
94+-- :& "booking_classes" (JArray :% (LengthArrLe 5) (JString :% Regexp "[a-zA-Z]{2}"))