module Data.Rawr
(
Strictness(..), Field(..), (:=), (:=!)
, pattern (:=), pattern (:=!), pattern Field, pattern Field'
, R, pattern R, pattern P
, (:!!)(..)
, (:*:), pattern (:*:)
, (::*:)
, (:~)
) where
import Control.DeepSeq
import Data.Functor.Const
import Data.Foldable
import Data.Proxy
import GHC.Generics (Generic)
import GHC.TypeLits
import GHC.Types
import GHC.OverloadedLabels
import Language.Haskell.TH hiding (Strict)
type (:~) r (f :: * -> Constraint) = f r
infix 0 :~
data Strictness = Lazy | Strict
data Field (s :: Strictness) (l :: Maybe Symbol) t = MkField { unField :: t } deriving (Eq, Ord, Generic, NFData)
instance (Monoid t) => Monoid (Field s l t) where
mempty = MkField mempty
MkField x `mappend` MkField y = MkField (x `mappend` y)
class WrapInField t f where
wrapInField :: t -> f
instance WrapInField t (Field 'Lazy l t) where
wrapInField t = MkField t
instance WrapInField t (Field 'Strict l t) where
wrapInField !t = MkField t
type family (:=) (l :: Symbol) (t :: *) = (f :: *) | f -> l t where
(:=) l t = Field 'Lazy ('Just l) t
type family (:=!) (l :: Symbol) (t :: *) = (f :: *) | f -> l t where
(:=!) l t = Field 'Strict ('Just l) t
infix 2 :=
infix 2 :=!
pattern (:=) :: KnownSymbol l => Proxy l -> t -> Field 'Lazy ('Just l) t
pattern p := t <- ((\(MkField t) -> (Proxy :: Proxy l, t)) -> (p, t)) where
_ := t = MkField t
pattern (:=!) :: KnownSymbol l => Proxy l -> t -> Field 'Strict ('Just l) t
pattern p :=! t <- ((\(MkField t) -> (Proxy :: Proxy l, t)) -> (p, t)) where
_ :=! (!t) = MkField t
pattern Field :: t -> Field 'Lazy 'Nothing t
pattern Field t <- (unField -> t) where
Field t = MkField t
pattern Field' :: t -> Field 'Strict 'Nothing t
pattern Field' t <- (unField -> t) where
Field' !t = MkField t
instance (KnownSymbol l, Show t) => Show (Field 'Lazy ('Just l) t) where
show (l := t) = symbolVal l ++ " := " ++ show t
instance (KnownSymbol l, Show t) => Show (Field 'Strict ('Just l) t) where
show (l :=! t) = symbolVal l ++ " :=! " ++ show t
instance Show t => Show (Field s 'Nothing t) where
show (MkField t) = show t
type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
view :: Lens' s a -> s -> a
view l = getConst . l Const
instance l ~ l' => IsLabel (l :: Symbol) (Proxy l') where
fromLabel _ = Proxy
class (:!!) s (l :: Symbol) a | s l -> a where
fieldLens :: Lens' s a
data family Rec (xs :: [*])
data instance Rec '[] = R0
newtype instance Rec '[ Field s0 l0 t0 ] = R1 (Field s0 l0 t0)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 ] =
R2 !(Field s0 l0 t0) !(Field s1 l1 t1)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 ] =
R3 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 , Field s3 l3 t3 ] =
R4 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2) !(Field s3 l3 t3)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 , Field s3 l3 t3 , Field s4 l4 t4 ] =
R5 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2) !(Field s3 l3 t3) !(Field s4 l4 t4)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 , Field s3 l3 t3 , Field s4 l4 t4 , Field s5 l5 t5 ] =
R6 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2) !(Field s3 l3 t3) !(Field s4 l4 t4) !(Field s5 l5 t5)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 , Field s3 l3 t3 , Field s4 l4 t4 , Field s5 l5 t5 , Field s6 l6 t6 ] =
R7 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2) !(Field s3 l3 t3) !(Field s4 l4 t4) !(Field s5 l5 t5) !(Field s6 l6 t6)
data instance Rec '[ Field s0 l0 t0 , Field s1 l1 t1 , Field s2 l2 t2 , Field s3 l3 t3 , Field s4 l4 t4 , Field s5 l5 t5 , Field s6 l6 t6 , Field s7 l7 t7 ] =
R8 !(Field s0 l0 t0) !(Field s1 l1 t1) !(Field s2 l2 t2) !(Field s3 l3 t3) !(Field s4 l4 t4) !(Field s5 l5 t5) !(Field s6 l6 t6) !(Field s7 l7 t7)
$(
return $ do
let s = VarT (mkName "s")
l = VarT (mkName "l")
t = VarT (mkName "t")
mkField s' l' t' = ConT ''Field `AppT` s' `AppT` (ConT 'Just `AppT` l') `AppT` t'
fieldslt = mkField s l t
f = mkName "f"
x = mkName "x"
x' = mkName "x'"
cxt = [ConT ''WrapInField `AppT` t `AppT` fieldslt]
n :: Integer <- [1 .. 8]
i <- [1 .. n]
let recList = [ if i == i' then fieldslt else mkField (VarT (mkName ("s" ++ show i'))) (VarT (mkName ("l" ++ show i'))) (VarT (mkName ("t" ++ show i'))) | i' <- [1 .. n] ]
recTy = ConT ''Rec `AppT` foldr (\t ts -> (PromotedConsT `AppT` t) `AppT` ts) PromotedNilT recList
ty = ConT ''(:!!) `AppT` recTy `AppT` l `AppT` t
rPat = ConP (mkName ("R" ++ show n)) [ if i == i' then ConP 'MkField [VarP x] else VarP (mkName ("_" ++ show i')) | i' <- [1 .. n] ]
rExp = foldl' AppE (ConE (mkName ("R" ++ show n))) [ if i == i' then AppE (VarE 'wrapInField) (VarE x') else VarE (mkName ("_" ++ show i')) | i' <- [1 .. n] ]
body = NormalB $ UInfixE (LamE [VarP x'] rExp) (VarE '(<$>)) (VarE f `AppE` VarE x)
fieldLensFn = FunD 'fieldLens [Clause [VarP (mkName "f"), rPat] body []]
return $ InstanceD Nothing cxt ty [fieldLensFn]
)
instance Show (Rec '[]) where
show _ = "R ()"
instance Show (Field s0 l0 t0) => Show (Rec '[Field s0 l0 t0]) where
show (R1 a) = "R ( " ++ show a ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1)) => Show (Rec '[Field s0 l0 t0, Field s1 l1 t1]) where
show (R2 a b) = "R ( " ++ show a ++ ", " ++ show b ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2)) => Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) where
show (R3 a b c) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2), Show (Field s3 l3 t3))
=> Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) where
show (R4 a b c d) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ ", " ++ show d ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2), Show (Field s3 l3 t3), Show (Field s4 l4 t4))
=> Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) where
show (R5 a b c d e) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ ", " ++ show d ++ ", " ++ show e ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2), Show (Field s3 l3 t3), Show (Field s4 l4 t4), Show (Field s5 l5 t5))
=> Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) where
show (R6 a b c d e f) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ ", " ++ show d ++ ", " ++ show e ++ ", " ++ show f ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2), Show (Field s3 l3 t3), Show (Field s4 l4 t4), Show (Field s5 l5 t5), Show (Field s6 l6 t6))
=> Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) where
show (R7 a b c d e f g) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ ", " ++ show d ++ ", " ++ show e ++ ", " ++ show f ++ ", " ++ show g ++ " )"
instance (Show (Field s0 l0 t0), Show (Field s1 l1 t1), Show (Field s2 l2 t2), Show (Field s3 l3 t3), Show (Field s4 l4 t4), Show (Field s5 l5 t5), Show (Field s6 l6 t6), Show (Field s7 l7 t7))
=> Show (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) where
show (R8 a b c d e f g h) = "R ( " ++ show a ++ ", " ++ show b ++ ", " ++ show c ++ ", " ++ show d ++ ", " ++ show e ++ ", " ++ show f ++ ", " ++ show g ++ ", " ++ show h ++ " )"
deriving instance Eq (Rec '[])
deriving instance (Eq t0) => Eq (Rec '[Field s0 l0 t0])
deriving instance (Eq t0, Eq t1) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1])
deriving instance (Eq t0, Eq t1, Eq t2) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2])
deriving instance (Eq t0, Eq t1, Eq t2, Eq t3) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3])
deriving instance (Eq t0, Eq t1, Eq t2, Eq t3, Eq t4) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4])
deriving instance (Eq t0, Eq t1, Eq t2, Eq t3, Eq t4, Eq t5) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5])
deriving instance (Eq t0, Eq t1, Eq t2, Eq t3, Eq t4, Eq t5, Eq t6) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6])
deriving instance (Eq t0, Eq t1, Eq t2, Eq t3, Eq t4, Eq t5, Eq t6, Eq t7) => Eq (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7])
deriving instance Ord (Rec '[])
deriving instance (Ord t0) => Ord (Rec '[Field s0 l0 t0])
deriving instance (Ord t0, Ord t1) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1])
deriving instance (Ord t0, Ord t1, Ord t2) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2])
deriving instance (Ord t0, Ord t1, Ord t2, Ord t3) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3])
deriving instance (Ord t0, Ord t1, Ord t2, Ord t3, Ord t4) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4])
deriving instance (Ord t0, Ord t1, Ord t2, Ord t3, Ord t4, Ord t5) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5])
deriving instance (Ord t0, Ord t1, Ord t2, Ord t3, Ord t4, Ord t5, Ord t6) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6])
deriving instance (Ord t0, Ord t1, Ord t2, Ord t3, Ord t4, Ord t5, Ord t6, Ord t7) => Ord (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7])
instance NFData (Rec '[]) where
rnf R0 = ()
instance (NFData t0) => NFData (Rec '[Field s0 l0 t0]) where
rnf (R1 a) = rnf a
instance (NFData t0, NFData t1) => NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1]) where
rnf (R2 a b) = rnf a `seq` rnf b
instance (NFData t0, NFData t1, NFData t2) => NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) where
rnf (R3 a b c) = rnf a `seq` rnf b `seq` rnf c
instance (NFData t0, NFData t1, NFData t2, NFData t3) => NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) where
rnf (R4 a b c d) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d
instance (NFData t0, NFData t1, NFData t2, NFData t3, NFData t4) => NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) where
rnf (R5 a b c d e) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e
instance (NFData t0, NFData t1, NFData t2, NFData t3, NFData t4, NFData t5) => NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) where
rnf (R6 a b c d e f) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e `seq` rnf f
instance (NFData t0, NFData t1, NFData t2, NFData t3, NFData t4, NFData t5, NFData t6)
=> NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) where
rnf (R7 a b c d e f g) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e `seq` rnf f `seq` rnf g
instance (NFData t0, NFData t1, NFData t2, NFData t3, NFData t4, NFData t5, NFData t6, NFData t7)
=> NFData (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) where
rnf (R8 a b c d e f g h) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e `seq` rnf f `seq` rnf g `seq` rnf h
instance Monoid (Rec '[]) where
mempty = R0
_ `mappend` _ = R0
instance (Monoid t0) => Monoid (Rec '[Field s0 l0 t0]) where
mempty = R1 mempty
R1 a `mappend` R1 a' = R1 (a `mappend` a')
instance (Monoid t0, Monoid t1) => Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1]) where
mempty = R2 mempty mempty
R2 a b `mappend` R2 a' b' = R2 (a `mappend` a') (b `mappend` b')
instance (Monoid t0, Monoid t1, Monoid t2) => Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) where
mempty = R3 mempty mempty mempty
R3 a b c `mappend` R3 a' b' c' = R3 (a `mappend` a') (b `mappend` b') (c `mappend` c')
instance (Monoid t0, Monoid t1, Monoid t2, Monoid t3) => Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) where
mempty = R4 mempty mempty mempty mempty
R4 a b c d `mappend` R4 a' b' c' d' = R4 (a `mappend` a') (b `mappend` b') (c `mappend` c') (d `mappend` d')
instance (Monoid t0, Monoid t1, Monoid t2, Monoid t3, Monoid t4) => Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) where
mempty = R5 mempty mempty mempty mempty mempty
R5 a b c d e `mappend` R5 a' b' c' d' e' = R5 (a `mappend` a') (b `mappend` b') (c `mappend` c') (d `mappend` d') (e `mappend` e')
instance (Monoid t0, Monoid t1, Monoid t2, Monoid t3, Monoid t4, Monoid t5) =>
Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) where
mempty = R6 mempty mempty mempty mempty mempty mempty
R6 a b c d e f `mappend` R6 a' b' c' d' e' f' = R6 (a `mappend` a') (b `mappend` b') (c `mappend` c') (d `mappend` d') (e `mappend` e') (f `mappend` f')
instance (Monoid t0, Monoid t1, Monoid t2, Monoid t3, Monoid t4, Monoid t5, Monoid t6) =>
Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) where
mempty = R7 mempty mempty mempty mempty mempty mempty mempty
R7 a b c d e f g `mappend` R7 a' b' c' d' e' f' g' = R7 (a `mappend` a') (b `mappend` b') (c `mappend` c') (d `mappend` d') (e `mappend` e') (f `mappend` f') (g `mappend` g')
instance (Monoid t0, Monoid t1, Monoid t2, Monoid t3, Monoid t4, Monoid t5, Monoid t6, Monoid t7) =>
Monoid (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) where
mempty = R8 mempty mempty mempty mempty mempty mempty mempty mempty
R8 a b c d e f g h `mappend` R8 a' b' c' d' e' f' g' h' = R8 (a `mappend` a') (b `mappend` b') (c `mappend` c') (d `mappend` d') (e `mappend` e') (f `mappend` f') (g `mappend` g') (h `mappend` h')
instance
( a ~ TypeError (Text "Label " :<>: ShowType l :<>: Text " does not occur in " :<>: PPRec s)
) => (:!!) s l a where
fieldLens = undefined
instance (a :~ s :!! l, Functor f, a ~ b, s2fs ~ (s -> f s)) => IsLabel (l :: Symbol) ((a -> f b) -> s2fs) where
fromLabel _ = fieldLens @s @l
instance (a :~ Rec xs :!! l) => IsLabel (l :: Symbol) (Rec xs -> a) where
fromLabel _ = view (fieldLens @(Rec xs) @l)
type family ToField (a :: *) = (r :: *) where
ToField (Field s l t) = Field s l t
ToField a = Field 'Lazy 'Nothing a
class (r ~ ToField a) => ToFieldImpl (a :: *) (r :: *) | a -> r where
toField :: a -> r
instance (r ~ Field s l t) => ToFieldImpl (Field s l t) r where
toField = id
instance (r ~ Field 'Lazy 'Nothing a, r ~ ToField a) => ToFieldImpl a r where
toField = Field
type family R (t :: *) = (r :: *) where
R () = Rec '[]
R (a, b) = Rec '[ToField a] :*: Rec '[ToField b]
R (a, b, c) = Rec '[ToField a] :*: (Rec '[ToField b] :*: Rec '[ToField c])
R (a, b, c, d) = (Rec '[ToField a] :*: Rec '[ToField b]) :*: (Rec '[ToField c] :*: Rec '[ToField d])
R (a, b, c, d, e) = (Rec '[ToField a] :*: Rec '[ToField b]) :*: (Rec '[ToField c] :*: (Rec '[ToField d] :*: Rec '[ToField e]))
R (a, b, c, d, e, f) = (Rec '[ToField a] :*: (Rec '[ToField b] :*: Rec '[ToField c])) :*: (Rec '[ToField d] :*: (Rec '[ToField e] :*: Rec '[ToField f]))
R (a, b, c, d, e, f, g) = (Rec '[ToField a] :*: (Rec '[ToField b] :*: Rec '[ToField c])) :*: ((Rec '[ToField d] :*: Rec '[ToField e]) :*: (Rec '[ToField f] :*: Rec '[ToField g]))
R (a, b, c, d, e, f, g, h) = ((Rec '[ToField a] :*: Rec '[ToField b]) :*: (Rec '[ToField c] :*: Rec '[ToField d])) :*: ((Rec '[ToField e] :*: Rec '[ToField f]) :*: (Rec '[ToField g] :*: Rec '[ToField h]))
R a = Rec '[ToField a]
class (r ~ R t) => RImpl (t :: *) (r :: *) | t -> r where
toR :: t -> r
instance (r ~ Rec '[]) => RImpl () r where
toR () = R0
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, r ~ Rec '[Field s0 l0 t0]
, r ~ R a
) => RImpl a r where
toR (toField -> a) = R1 a
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, r :~ RecMergeImpl (Rec '[Field s0 l0 t0]) (Rec '[Field s1 l1 t1])
, r ~ R (a, b)
) => RImpl (a, b) r where
toR (toField -> a, toField -> b) = R1 a `recMerge` R1 b
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, rr :~ RecMergeImpl (Rec '[Field s1 l1 t1]) (Rec '[Field s2 l2 t2])
, r :~ RecMergeImpl (Rec '[Field s0 l0 t0]) rr
, r ~ R (a, b, c)
) => RImpl (a, b, c) r where
toR (toField -> a, toField -> b, toField -> c) = R1 a `recMerge` (R1 b `recMerge` R1 c)
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, Field s3 l3 t3 :~ ToFieldImpl d
, rl :~ RecMergeImpl (Rec '[Field s0 l0 t0]) (Rec '[Field s1 l1 t1])
, rr :~ RecMergeImpl (Rec '[Field s2 l2 t2]) (Rec '[Field s3 l3 t3])
, r :~ RecMergeImpl rl rr
, r ~ R (a, b, c, d)
) => RImpl (a, b, c, d) r where
toR (toField -> a, toField -> b, toField -> c, toField -> d) = (R1 a `recMerge` R1 b) `recMerge` (R1 c `recMerge` R1 d)
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, Field s3 l3 t3 :~ ToFieldImpl d
, Field s4 l4 t4 :~ ToFieldImpl e
, rl :~ RecMergeImpl (Rec '[Field s0 l0 t0]) (Rec '[Field s1 l1 t1])
, rrr :~ RecMergeImpl (Rec '[Field s3 l3 t3]) (Rec '[Field s4 l4 t4])
, rr :~ RecMergeImpl (Rec '[Field s2 l2 t2]) rrr
, r :~ RecMergeImpl rl rr
, r ~ R (a, b, c, d, e)
) => RImpl (a, b, c, d, e) r where
toR (toField -> a, toField -> b, toField -> c, toField -> d, toField -> e) = (R1 a `recMerge` R1 b) `recMerge` (R1 c `recMerge` (R1 d `recMerge` R1 e))
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, Field s3 l3 t3 :~ ToFieldImpl d
, Field s4 l4 t4 :~ ToFieldImpl e
, Field s5 l5 t5 :~ ToFieldImpl f
, rlr :~ RecMergeImpl (Rec '[Field s1 l1 t1]) (Rec '[Field s2 l2 t2])
, rl :~ RecMergeImpl (Rec '[Field s0 l0 t0]) rlr
, rrr :~ RecMergeImpl (Rec '[Field s4 l4 t4]) (Rec '[Field s5 l5 t5])
, rr :~ RecMergeImpl (Rec '[Field s3 l3 t3]) rrr
, r :~ RecMergeImpl rl rr
, r ~ R (a, b, c, d, e, f)
) => RImpl (a, b, c, d, e, f) r where
toR (toField -> a, toField -> b, toField -> c, toField -> d, toField -> e, toField -> f) =
(R1 a `recMerge` (R1 b `recMerge` R1 c)) `recMerge` (R1 d `recMerge` (R1 e `recMerge` R1 f))
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, Field s3 l3 t3 :~ ToFieldImpl d
, Field s4 l4 t4 :~ ToFieldImpl e
, Field s5 l5 t5 :~ ToFieldImpl f
, Field s6 l6 t6 :~ ToFieldImpl g
, rlr :~ RecMergeImpl (Rec '[Field s1 l1 t1]) (Rec '[Field s2 l2 t2])
, rl :~ RecMergeImpl (Rec '[Field s0 l0 t0]) rlr
, rrl :~ RecMergeImpl (Rec '[Field s3 l3 t3]) (Rec '[Field s4 l4 t4])
, rrr :~ RecMergeImpl (Rec '[Field s5 l5 t5]) (Rec '[Field s6 l6 t6])
, rr :~ RecMergeImpl rrl rrr
, r :~ RecMergeImpl rl rr
, r ~ R (a, b, c, d, e, f, g)
) => RImpl (a, b, c, d, e, f, g) r where
toR (toField -> a, toField -> b, toField -> c, toField -> d, toField -> e, toField -> f, toField -> g) =
(R1 a `recMerge` (R1 b `recMerge` R1 c)) `recMerge` ((R1 d `recMerge` R1 e) `recMerge` (R1 f `recMerge` R1 g))
instance
( Field s0 l0 t0 :~ ToFieldImpl a
, Field s1 l1 t1 :~ ToFieldImpl b
, Field s2 l2 t2 :~ ToFieldImpl c
, Field s3 l3 t3 :~ ToFieldImpl d
, Field s4 l4 t4 :~ ToFieldImpl e
, Field s5 l5 t5 :~ ToFieldImpl f
, Field s6 l6 t6 :~ ToFieldImpl g
, Field s7 l7 t7 :~ ToFieldImpl h
, rll :~ RecMergeImpl (Rec '[Field s0 l0 t0]) (Rec '[Field s1 l1 t1])
, rlr :~ RecMergeImpl (Rec '[Field s2 l2 t2]) (Rec '[Field s3 l3 t3])
, rl :~ RecMergeImpl rll rlr
, rrl :~ RecMergeImpl (Rec '[Field s4 l4 t4]) (Rec '[Field s5 l5 t5])
, rrr :~ RecMergeImpl (Rec '[Field s6 l6 t6]) (Rec '[Field s7 l7 t7])
, rr :~ RecMergeImpl rrl rrr
, r :~ RecMergeImpl rl rr
, r ~ R (a, b, c, d, e, f, g, h)
) => RImpl (a, b, c, d, e, f, g, h) r where
toR (toField -> a, toField -> b, toField -> c, toField -> d, toField -> e, toField -> f, toField -> g, toField -> h) =
((R1 a `recMerge` R1 b) `recMerge` (R1 c `recMerge` R1 d)) `recMerge` ((R1 e `recMerge` R1 f) `recMerge` (R1 g `recMerge` R1 h))
class UnRImpl r t where
unR :: r -> t
instance UnRImpl r () where
unR _ = ()
type ReWrap r s l t = ( t :~ r :!! l, Field s ('Just l) t :~ WrapInField t)
instance (ReWrap r s0 l0 t0) => UnRImpl r (Field s0 ('Just l0) t0) where
unR r = wrapInField $ view (fieldLens @r @l0) r
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1) => UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2) => UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2, ReWrap r s3 l3 t3)
=> UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2, Field s3 ('Just l3) t3) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
, wrapInField $ view (fieldLens @r @l3) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2, ReWrap r s3 l3 t3, ReWrap r s4 l4 t4)
=> UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2, Field s3 ('Just l3) t3, Field s4 ('Just l4) t4) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
, wrapInField $ view (fieldLens @r @l3) r
, wrapInField $ view (fieldLens @r @l4) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2, ReWrap r s3 l3 t3, ReWrap r s4 l4 t4, ReWrap r s5 l5 t5)
=> UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2, Field s3 ('Just l3) t3, Field s4 ('Just l4) t4, Field s5 ('Just l5) t5) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
, wrapInField $ view (fieldLens @r @l3) r
, wrapInField $ view (fieldLens @r @l4) r
, wrapInField $ view (fieldLens @r @l5) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2, ReWrap r s3 l3 t3, ReWrap r s4 l4 t4, ReWrap r s5 l5 t5, ReWrap r s6 l6 t6)
=> UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2, Field s3 ('Just l3) t3, Field s4 ('Just l4) t4, Field s5 ('Just l5) t5, Field s6 ('Just l6) t6) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
, wrapInField $ view (fieldLens @r @l3) r
, wrapInField $ view (fieldLens @r @l4) r
, wrapInField $ view (fieldLens @r @l5) r
, wrapInField $ view (fieldLens @r @l6) r
)
instance (ReWrap r s0 l0 t0, ReWrap r s1 l1 t1, ReWrap r s2 l2 t2, ReWrap r s3 l3 t3, ReWrap r s4 l4 t4, ReWrap r s5 l5 t5, ReWrap r s6 l6 t6, ReWrap r s7 l7 t7)
=> UnRImpl r (Field s0 ('Just l0) t0, Field s1 ('Just l1) t1, Field s2 ('Just l2) t2, Field s3 ('Just l3) t3, Field s4 ('Just l4) t4, Field s5 ('Just l5) t5, Field s6 ('Just l6) t6, Field s7 ('Just l7) t7) where
unR r = ( wrapInField $ view (fieldLens @r @l0) r
, wrapInField $ view (fieldLens @r @l1) r
, wrapInField $ view (fieldLens @r @l2) r
, wrapInField $ view (fieldLens @r @l3) r
, wrapInField $ view (fieldLens @r @l4) r
, wrapInField $ view (fieldLens @r @l5) r
, wrapInField $ view (fieldLens @r @l6) r
, wrapInField $ view (fieldLens @r @l7) r
)
instance UnRImpl (Rec '[Field s0 'Nothing t0]) t0 where
unR (R1 (MkField a)) = a
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1]) (t0, t1) where
unR (R2 (MkField a) (MkField b)) = (a, b)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2]) (t0, t1, t2) where
unR (R3 (MkField a) (MkField b) (MkField c)) = (a, b, c)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3]) (t0, t1, t2, t3) where
unR (R4 (MkField a) (MkField b) (MkField c) (MkField d)) = (a, b, c, d)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4])
(t0, t1, t2, t3, t4) where
unR (R5 (MkField a) (MkField b) (MkField c) (MkField d) (MkField e)) = (a, b, c, d, e)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5])
(t0, t1, t2, t3, t4, t5) where
unR (R6 (MkField a) (MkField b) (MkField c) (MkField d) (MkField e) (MkField f)) = (a, b, c, d, e, f)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6])
(t0, t1, t2, t3, t4, t5, t6) where
unR (R7 (MkField a) (MkField b) (MkField c) (MkField d) (MkField e) (MkField f) (MkField g)) = (a, b, c, d, e, f, g)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6, Field s7 'Nothing t7])
(t0, t1, t2, t3, t4, t5, t6, t7) where
unR (R8 (MkField a) (MkField b) (MkField c) (MkField d) (MkField e) (MkField f) (MkField g) (MkField h)) = (a, b, c, d, e, f, g, h)
instance UnRImpl (Rec '[Field s0 'Nothing t0]) (Field s0 'Nothing t0) where
unR (R1 a) = a
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1])
(Field s0 'Nothing t0, Field s1 'Nothing t1) where
unR (R2 a b) = (a, b)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2) where
unR (R3 a b c) = (a, b, c)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3) where
unR (R4 a b c d) = (a, b, c, d)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4) where
unR (R5 a b c d e) = (a, b, c, d, e)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5) where
unR (R6 a b c d e f) = (a, b, c, d, e, f)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6) where
unR (R7 a b c d e f g) = (a, b, c, d, e, f, g)
instance UnRImpl (Rec '[Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6, Field s7 'Nothing t7])
(Field s0 'Nothing t0, Field s1 'Nothing t1, Field s2 'Nothing t2, Field s3 'Nothing t3, Field s4 'Nothing t4, Field s5 'Nothing t5, Field s6 'Nothing t6, Field s7 'Nothing t7) where
unR (R8 a b c d e f g h) = (a, b, c, d, e, f, g, h)
pattern R :: (r :~ RImpl t, t :~ UnRImpl r) => t -> r
pattern R x <- (unR -> x) where
R = toR
pattern P :: (t :~ UnRImpl r) => t -> r
pattern P x <- (unR -> x)
type family RecHead (r :: *) :: * where
RecHead (Rec '[a, b, c, d, e, f, g, h]) = a
RecHead (Rec '[a, b, c, d, e, f, g]) = a
RecHead (Rec '[a, b, c, d, e, f]) = a
RecHead (Rec '[a, b, c, d, e]) = a
RecHead (Rec '[a, b, c, d]) = a
RecHead (Rec '[a, b, c]) = a
RecHead (Rec '[a, b]) = a
RecHead (Rec '[a]) = a
class (r ~ RecHead a) => RecHeadImpl a r | a -> r where
recHead :: a -> r
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) (Field s0 l0 t0) where
recHead (R8 a _ _ _ _ _ _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) (Field s0 l0 t0) where
recHead (R7 a _ _ _ _ _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) (Field s0 l0 t0) where
recHead (R6 a _ _ _ _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) (Field s0 l0 t0) where
recHead (R5 a _ _ _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) (Field s0 l0 t0) where
recHead (R4 a _ _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) (Field s0 l0 t0) where
recHead (R3 a _ _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1]) (Field s0 l0 t0) where
recHead (R2 a _) = a
instance RecHeadImpl (Rec '[Field s0 l0 t0]) (Field s0 l0 t0) where
recHead (R1 a) = a
type family RecTail (r :: *) :: * where
RecTail (Rec '[a, b, c, d, e, f, g, h]) = Rec '[b, c, d, e, f, g, h]
RecTail (Rec '[a, b, c, d, e, f, g]) = Rec '[b, c, d, e, f, g]
RecTail (Rec '[a, b, c, d, e, f]) = Rec '[b, c, d, e, f]
RecTail (Rec '[a, b, c, d, e]) = Rec '[b, c, d, e]
RecTail (Rec '[a, b, c, d]) = Rec '[b, c, d]
RecTail (Rec '[a, b, c]) = Rec '[b, c]
RecTail (Rec '[a, b]) = Rec '[b]
RecTail (Rec '[a]) = Rec '[]
class (r ~ RecTail a) => RecTailImpl a r | a -> r where
recTail :: a -> r
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7])
(Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) where
recTail (R8 _ b c d e f g h) = R7 b c d e f g h
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6])
(Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) where
recTail (R7 _ b c d e f g) = R6 b c d e f g
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5])
(Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) where
recTail (R6 _ b c d e f) = R5 b c d e f
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) where
recTail (R5 _ b c d e) = R4 b c d e
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) where
recTail (R4 _ b c d) = R3 b c d
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) (Rec '[Field s1 l1 t1, Field s2 l2 t2]) where
recTail (R3 _ b c) = R2 b c
instance RecTailImpl (Rec '[Field s0 l0 t0, Field s1 l1 t1]) (Rec '[Field s1 l1 t1]) where
recTail (R2 _ b) = R1 b
instance RecTailImpl (Rec '[Field s0 l0 t0]) (Rec '[]) where
recTail (R1 _) = R0
type family RecCons (x :: *) (xs :: *) = (r :: *) | r -> x xs where
RecCons a (Rec '[b, c, d, e, f, g, h]) = Rec '[a, b, c, d, e, f, g, h]
RecCons a (Rec '[b, c, d, e, f, g]) = Rec '[a, b, c, d, e, f, g]
RecCons a (Rec '[b, c, d, e, f]) = Rec '[a, b, c, d, e, f]
RecCons a (Rec '[b, c, d, e]) = Rec '[a, b, c, d, e]
RecCons a (Rec '[b, c, d]) = Rec '[a, b, c, d]
RecCons a (Rec '[b, c]) = Rec '[a, b, c]
RecCons a (Rec '[b]) = Rec '[a, b]
RecCons a (Rec '[]) = Rec '[a]
class (r ~ RecCons x xs) => RecConsImpl x xs r | x xs -> r, r -> x xs where
recCons :: x -> xs -> r
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7])
(Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) where
recCons a (R7 b c d e f g h) = R8 a b c d e f g h
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6])
(Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) where
recCons a (R6 b c d e f g) = R7 a b c d e f g
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5])
(Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) where
recCons a (R5 b c d e f) = R6 a b c d e f
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) where
recCons a (R4 b c d e) = R5 a b c d e
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) where
recCons a (R3 b c d) = R4 a b c d
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1, Field s2 l2 t2]) (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) where
recCons a (R2 b c) = R3 a b c
instance RecConsImpl (Field s0 l0 t0) (Rec '[Field s1 l1 t1]) (Rec '[Field s0 l0 t0, Field s1 l1 t1]) where
recCons a (R1 b) = R2 a b
instance RecConsImpl (Field s0 l0 t0) (Rec '[]) (Rec '[Field s0 l0 t0]) where
recCons a R0 = R1 a
type family RecMerge (xs :: *) (ys :: *) = (r :: *) where
RecMerge (Rec '[]) (Rec ys) = Rec ys
RecMerge (Rec xs) (Rec '[]) = Rec xs
RecMerge (Rec (Field sx ('Just lx) tx ': xs)) (Rec (Field sy ('Just ly) ty ': ys)) = RecMerge' (CmpSymbol lx ly) (Rec (Field sx ('Just lx) tx ': xs)) (Rec (Field sy ('Just ly) ty ': ys))
RecMerge (Rec (Field sx ('Just lx) tx ': xs)) (Rec (Field sy 'Nothing ty ': ys)) = TypeError (Text "RecMerge: Cannot merge labeled and unlabeled fields")
RecMerge (Rec (Field sx 'Nothing tx ': xs)) (Rec (Field sy ('Just l) ty ': ys)) = TypeError (Text "RecMerge: Cannot merge labeled and unlabeled fields")
RecMerge (Rec (Field sx 'Nothing tx ': xs)) (Rec (Field sy 'Nothing ty ': ys)) = Field sx 'Nothing tx `RecCons` (Rec xs `RecMerge` Rec (Field sy 'Nothing ty ': ys))
class (r ~ RecMerge xs ys) => RecMergeImpl (xs :: *) (ys :: *) (r :: *) | xs ys -> r where
recMerge :: xs -> ys -> r
instance RecMergeImpl (Rec '[]) (Rec ys) (Rec ys) where
recMerge R0 ys = ys
instance RecMergeImpl (Rec xs) (Rec '[]) (Rec xs) where
recMerge xs R0 = xs
instance ( r :~ RecMerge'Impl (CmpSymbol lx ly) (Rec (Field sx ('Just lx) tx ': xs)) (Rec (Field sy ('Just ly) ty ': ys))
) => RecMergeImpl (Rec (Field sx ('Just lx) tx ': xs)) (Rec (Field sy ('Just ly) ty ': ys)) r where
recMerge = recMerge' @(CmpSymbol lx ly)
instance ( r ~ RecMerge (Rec (Field s ('Just l) t ': xs)) (Rec (Field sy 'Nothing ty ': ys))
) => RecMergeImpl (Rec (Field s ('Just l) t ': xs)) (Rec (Field sy 'Nothing ty ': ys)) r where
recMerge = undefined
instance ( r ~ RecMerge (Rec (Field s 'Nothing t ': xs)) (Rec (Field s' ('Just l) t' ': ys))
) => RecMergeImpl (Rec (Field s 'Nothing t ': xs)) (Rec (Field s' ('Just l) t' ': ys)) r where
recMerge = undefined
instance ( Field sx 'Nothing tx :~ RecHeadImpl (Rec (Field sx 'Nothing tx ': xs))
, Rec xs :~ RecTailImpl (Rec (Field sx 'Nothing tx ': xs))
, r' :~ RecMergeImpl (Rec xs) (Rec (Field sy 'Nothing ty ': ys))
, r :~ RecConsImpl (Field sx 'Nothing tx) r'
, r ~ RecMerge (Rec (Field sx 'Nothing tx ': xs)) (Rec (Field sy 'Nothing ty ': ys))
) => RecMergeImpl (Rec (Field sx 'Nothing tx ': xs)) (Rec (Field sy 'Nothing ty ': ys)) r where
recMerge xs ys = recHead xs `recCons` (recTail xs `recMerge` ys)
type family RecMerge' (ord :: Ordering) (xs :: *) (ys :: *) = (r :: *) where
RecMerge' 'EQ (Rec (Field _ ('Just l) _ ': _)) _ = TypeError (Text "Duplicate labels " :<>: ShowType l)
RecMerge' 'LT (Rec (Field sx lx tx ': xs)) ys = Field sx lx tx `RecCons` (Rec xs `RecMerge` ys)
RecMerge' 'GT xs (Rec (Field sy ly ty ': ys)) = Field sy ly ty `RecCons` (xs `RecMerge` Rec ys)
class (r ~ RecMerge' ord xs ys) => RecMerge'Impl (ord :: Ordering) (xs :: *) (ys :: *) (r :: *) | ord xs ys -> r where
recMerge' :: xs -> ys -> r
instance (r ~ RecMerge' 'EQ (Rec (Field sx l tx ': xs)) (Rec (Field sy l ty ': ys)))
=> RecMerge'Impl 'EQ (Rec (Field sx l tx ': xs)) (Rec (Field sy l ty ': ys)) r where
recMerge' = undefined
instance ( Field sx lx tx :~ RecHeadImpl (Rec (Field sx lx tx ': xs))
, Rec xs :~ RecTailImpl (Rec (Field sx lx tx ': xs))
, merged :~ RecMergeImpl (Rec xs) ys
, r :~ RecConsImpl (Field sx lx tx) merged
) => RecMerge'Impl 'LT (Rec (Field sx lx tx ': xs)) ys r where
recMerge' xs ys = recHead xs `recCons` (recTail xs `recMerge` ys)
instance ( Field sy ly ty :~ RecHeadImpl (Rec (Field sy ly ty ': ys))
, Rec ys :~ RecTailImpl (Rec (Field sy ly ty ': ys))
, merged :~ RecMergeImpl xs (Rec ys)
, r :~ RecConsImpl (Field sy ly ty) merged
) => RecMerge'Impl 'GT xs (Rec (Field sy ly ty ': ys)) r where
recMerge' xs ys = recHead ys `recCons` (xs `recMerge` recTail ys)
type family RecConsFst (x :: *) (xs :: *) = (r :: *) | r -> x xs where
RecConsFst x (Rec xs, Rec ys) = (x `RecCons` Rec xs, Rec ys)
class (r ~ RecConsFst x xs) => RecConsFstImpl (x :: *) (xs :: *) (r :: *) | x xs -> r, r -> x xs where
recConsFst :: x -> xs -> r
instance ( Rec xs' :~ RecConsImpl x (Rec xs)
, r ~ (Rec xs', Rec ys)
) => RecConsFstImpl x (Rec xs, Rec ys) r where
recConsFst x (xs, ys) = (x `recCons` xs, ys)
type family RecConsSnd (x :: *) (xs :: *) = (r :: *) | r -> x xs where
RecConsSnd x (Rec xs, Rec ys) = (Rec xs, x `RecCons` Rec ys)
class (r ~ RecConsSnd x xs) => RecConsSndImpl (x :: *) (xs :: *) (r :: *) | x xs -> r, r -> x xs where
recConsSnd :: x -> xs -> r
instance ( Rec ys' :~ RecConsImpl x (Rec ys)
, r ~ (Rec xs, Rec ys')
) => RecConsSndImpl x (Rec xs, Rec ys) r where
recConsSnd x (xs, ys) = (xs, x `recCons` ys)
type family RecPartition (xs :: *) (ys :: [*]) = (r :: *) where
RecPartition (Rec '[]) (Field s 'Nothing t ': ys) = TypeError (Text "RecPartition: Not enough fields in the record")
RecPartition (Rec '[]) (Field s ('Just l) t ': ys) = TypeError (Text "RecPartition: Label " :<>: ShowType l :<>: Text " does not occur in the record")
RecPartition (Rec xs) '[] = (Rec '[], Rec xs)
RecPartition (Rec (Field sx ('Just lx) tx ': xs)) (Field sy ('Just ly) ty ': ys) = RecPartition' (CmpSymbol lx ly) (Rec (Field sx ('Just lx) tx ': xs)) (Field sy ('Just ly) ty ': ys)
RecPartition (Rec (Field s 'Nothing t ': xs)) (Field s 'Nothing t ': ys) = RecConsFst (Field s 'Nothing t) (RecPartition (Rec xs) ys)
RecPartition (Rec (Field s 'Nothing tx ': xs)) (Field s 'Nothing ty ': ys) = TypeError (Text "RecPartition: type mismatch between " :<>: ShowType tx :<>: Text " and " :<>: ShowType ty)
type family RecPartition' (ord :: Ordering) (xs :: *) (ys :: [*]) = (r :: *) where
RecPartition' 'EQ (Rec (Field s l t ': xs)) (Field s l t ': ys) = Field s l t `RecConsFst` RecPartition (Rec xs) ys
RecPartition' 'EQ (Rec (Field sx ('Just l) tx ': xs)) (Field sy ('Just l) ty ': ys) = TypeError (Text "RecParition: type mismatch between " :<>: ShowType tx :<>: Text " and " :<>: ShowType ty :<>: Text " for label " :<>: ShowType l)
RecPartition' 'LT (Rec (Field s l t ': xs)) ys = Field s l t `RecConsSnd` RecPartition (Rec xs) ys
RecPartition' 'GT (Rec xs) (Field s ('Just l) t ': ys) = TypeError (Text "RecPartition: Label " :<>: ShowType l :<>: Text " does not occur in the record")
class (r ~ RecPartition xs ys) => RecPartitionImpl (xs :: *) (ys :: [*]) (r :: *) | xs ys -> r where
recPartition :: xs -> r
instance (r ~ RecPartition (Rec '[]) (Field s 'Nothing t ': ys)
) => RecPartitionImpl (Rec '[]) (Field s 'Nothing t ': ys) r where
recPartition = undefined
instance (r ~ RecPartition (Rec '[]) (Field s ('Just l) t ': ys)
) => RecPartitionImpl (Rec '[]) (Field s ('Just l) t ': ys) r where
recPartition = undefined
instance RecPartitionImpl (Rec xs) '[] (Rec '[], Rec xs) where
recPartition xs = (R0, xs)
instance ( r :~ RecPartition'Impl (CmpSymbol lx ly) (Rec (Field sx ('Just lx) tx ': xs)) (Field sy ('Just ly) ty ': ys)
) => RecPartitionImpl (Rec (Field sx ('Just lx) tx ': xs)) (Field sy ('Just ly) ty ': ys) r where
recPartition = recPartition' @(CmpSymbol lx ly) @(Rec (Field sx ('Just lx) tx ': xs)) @(Field sy ('Just ly) ty ': ys)
instance
( Field s 'Nothing t :~ RecHeadImpl (Rec (Field s 'Nothing t ': xs))
, Rec xs :~ RecTailImpl (Rec (Field s 'Nothing t ': xs))
, (Rec r0, Rec r1) :~ RecPartitionImpl (Rec xs) ys
, r :~ RecConsFstImpl (Field s 'Nothing t) (Rec r0, Rec r1)
) => RecPartitionImpl (Rec (Field s 'Nothing t ': xs)) (Field s 'Nothing t ': ys) r where
recPartition xs = recConsFst (recHead xs) (recPartition @(Rec xs) @ys (recTail xs))
instance
(r ~ RecPartition (Rec (Field s 'Nothing tx ': xs)) (Field s 'Nothing ty ': ys)
) => RecPartitionImpl (Rec (Field s 'Nothing tx ': xs)) (Field s 'Nothing ty ': ys) r where
recPartition = undefined
class (r ~ RecPartition' ord xs ys) => RecPartition'Impl (ord :: Ordering) (xs :: *) (ys :: [*]) (r :: *) | ord xs ys -> r where
recPartition' :: xs -> r
instance
( Field s l t :~ RecHeadImpl (Rec (Field s l t ': xs))
, Rec xs :~ RecTailImpl (Rec (Field s l t ': xs))
, (Rec r0, Rec r1) :~ RecPartitionImpl (Rec xs) ys
, r :~ RecConsFstImpl (Field s l t) (Rec r0, Rec r1)
) => RecPartition'Impl 'EQ (Rec (Field s l t ': xs)) (Field s l t ': ys) r where
recPartition' xs = recHead xs `recConsFst` recPartition @(Rec xs) @ys (recTail xs)
instance
( r ~ RecPartition' 'EQ (Rec (Field sx l tx ': xs)) (Field sy l ty ': ys))
=> RecPartition'Impl 'EQ (Rec (Field sx l tx ': xs)) (Field sy l ty ': ys) r where
recPartition' = undefined
instance ( Field s l t :~ RecHeadImpl (Rec (Field s l t ': xs))
, Rec xs :~ RecTailImpl (Rec (Field s l t ': xs))
, (Rec r0, Rec r1) :~ RecPartitionImpl (Rec xs) ys
, r :~ RecConsSndImpl (Field s l t) (Rec r0, Rec r1)
) => RecPartition'Impl 'LT (Rec (Field s l t ': xs)) ys r where
recPartition' xs = recHead xs `recConsSnd` recPartition @(Rec xs) @ys (recTail xs)
instance (r ~ RecPartition' 'GT (Rec xs) (Field s l t ': ys))
=> RecPartition'Impl 'GT (Rec xs) (Field s l t ': ys) r where
recPartition' = undefined
type (:*:) x y = x `RecMerge` y
infixr 1 :*:
type family RecFieldList (xs :: *) = (r :: [*]) where
RecFieldList (Rec xs) = xs
class (r :~ RecMergeImpl xs ys, (xs, ys) :~ RecPartitionImpl r (RecFieldList xs)) => (::*:) xs ys r
infix 1 ::*:
instance (r :~ RecMergeImpl xs ys, (xs, ys) :~ RecPartitionImpl r (RecFieldList xs)) => (::*:) xs ys r
pattern (:*:) :: forall xs ys r. (r :~ xs ::*: ys) => xs -> ys -> r
pattern (:*:) xs ys <- (recPartition @r @(RecFieldList xs) -> (xs, ys)) where
(:*:) xs ys = xs `recMerge` ys
type family PPRec (r :: *) = (e :: ErrorMessage) where
PPRec (Rec '[]) = Text "R ()"
PPRec (Rec '[Field s0 l0 t0]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text ", " :<>: PPField (Field s3 l3 t3) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text ", " :<>: PPField (Field s3 l3 t3) :<>: Text ", " :<>: PPField (Field s4 l4 t4) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text ", " :<>: PPField (Field s3 l3 t3) :<>: Text ", " :<>: PPField (Field s4 l4 t4) :<>: Text ", " :<>: PPField (Field s5 l5 t5) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text ", " :<>: PPField (Field s3 l3 t3) :<>: Text ", " :<>: PPField (Field s4 l4 t4) :<>: Text ", " :<>: PPField (Field s5 l5 t5) :<>: Text ", " :<>: PPField (Field s6 l6 t6) :<>: Text " )"
PPRec (Rec '[Field s0 l0 t0, Field s1 l1 t1, Field s2 l2 t2, Field s3 l3 t3, Field s4 l4 t4, Field s5 l5 t5, Field s6 l6 t6, Field s7 l7 t7]) =
Text "R ( " :<>: PPField (Field s0 l0 t0) :<>: Text ", " :<>: PPField (Field s1 l1 t1) :<>: Text ", " :<>: PPField (Field s2 l2 t2) :<>: Text ", " :<>: PPField (Field s3 l3 t3) :<>: Text ", " :<>: PPField (Field s4 l4 t4) :<>: Text ", " :<>: PPField (Field s5 l5 t5) :<>: Text ", " :<>: PPField (Field s6 l6 t6) :<>: Text ", " :<>: PPField (Field s7 l7 t7) :<>: Text " )"
type family PPField (r :: *) = (e :: ErrorMessage) where
PPField (Field 'Lazy 'Nothing t) = ShowType t
PPField (Field 'Strict 'Nothing t) = Text "!(" :<>: ShowType t :<>: Text ")"
PPField (Field 'Lazy ('Just l) t) = ShowType l :<>: Text " := " :<>: ShowType t
PPField (Field 'Strict ('Just l) t) = ShowType l :<>: Text " :=! " :<>: ShowType t
type (:<>:) x y = x ':<>: y
type Text x = 'Text x
type ShowType x = 'ShowType x