{-# LANGUAGE ConstraintKinds, DataKinds, FlexibleContexts, FlexibleInstances,
KindSignatures, MultiParamTypeClasses, PolyKinds,
ScopedTypeVariables, TypeFamilies, TypeOperators,
UndecidableInstances #-}
module Frames.Melt where
import Data.Proxy
import Data.Vinyl
import Data.Vinyl.CoRec (CoRec(..))
import Data.Vinyl.TypeLevel
import Frames.Col
import Frames.Frame (Frame(..), FrameRec)
import Frames.Rec
import Frames.RecF (ColumnHeaders(..))
type family Elem t ts :: Bool where
Elem t '[] = 'False
Elem t (t ': ts) = 'True
Elem t (s ': ts) = Elem t ts
type family Or (a :: Bool) (b :: Bool) :: Bool where
Or 'True b = 'True
Or a b = b
type family Not a :: Bool where
Not 'True = 'False
Not 'False = 'True
type family Disjoint ss ts :: Bool where
Disjoint '[] ts = 'True
Disjoint (s ': ss) ts = Or (Not (Elem s ts)) (Disjoint ss ts)
type ElemOf ts r = RElem r ts (RIndex r ts)
class RowToColumn ts rs where
rowToColumnAux :: Proxy ts -> Rec f rs -> [CoRec f ts]
instance RowToColumn ts '[] where
rowToColumnAux :: forall (f :: k -> *). Proxy ts -> Rec f '[] -> [CoRec f ts]
rowToColumnAux Proxy ts
_ Rec f '[]
_ = []
instance (r ∈ ts, RowToColumn ts rs) => RowToColumn ts (r ': rs) where
rowToColumnAux :: forall (f :: a -> *). Proxy ts -> Rec f (r : rs) -> [CoRec f ts]
rowToColumnAux Proxy ts
p (f r
x :& Rec f rs
xs) = forall {k} (a1 :: k) (b :: [k]) (a :: k -> *).
RElem a1 b (RIndex a1 b) =>
a a1 -> CoRec a b
CoRec f r
x forall a. a -> [a] -> [a]
: forall {k} (ts :: [k]) (rs :: [k]) (f :: k -> *).
RowToColumn ts rs =>
Proxy ts -> Rec f rs -> [CoRec f ts]
rowToColumnAux Proxy ts
p Rec f rs
xs
rowToColumn :: RowToColumn ts ts => Rec f ts -> [CoRec f ts]
rowToColumn :: forall {k} (ts :: [k]) (f :: k -> *).
RowToColumn ts ts =>
Rec f ts -> [CoRec f ts]
rowToColumn = forall {k} (ts :: [k]) (rs :: [k]) (f :: k -> *).
RowToColumn ts rs =>
Proxy ts -> Rec f rs -> [CoRec f ts]
rowToColumnAux forall {k} (t :: k). Proxy t
Proxy
meltAux :: forall vs ss ts.
(vs ⊆ ts, ss ⊆ ts, Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs)
=> Record ts
-> [Record ("value" :-> CoRec ElField vs ': ss)]
meltAux :: forall (vs :: [(Symbol, *)]) (ss :: [(Symbol, *)])
(ts :: [(Symbol, *)]).
(vs ⊆ ts, ss ⊆ ts, Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs) =>
Record ts -> [Record (("value" :-> CoRec ElField vs) : ss)]
meltAux Record ts
r = forall a b. (a -> b) -> [a] -> [b]
map (\CoRec ElField vs
val -> forall (t :: (Symbol, *)). Snd t -> ElField t
Field CoRec ElField vs
val forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Record ss
ids) (forall {k} (ts :: [k]) (f :: k -> *).
RowToColumn ts ts =>
Rec f ts -> [CoRec f ts]
rowToColumn Record vs
vals)
where ids :: Record ss
ids = forall {k1} {k2} (rs :: [k1]) (ss :: [k1]) (f :: k2 -> *)
(record :: (k2 -> *) -> [k1] -> *) (is :: [Nat]).
(RecSubset record rs ss is, RecSubsetFCtx record f) =>
record f ss -> record f rs
rcast Record ts
r :: Record ss
vals :: Record vs
vals = forall {k1} {k2} (rs :: [k1]) (ss :: [k1]) (f :: k2 -> *)
(record :: (k2 -> *) -> [k1] -> *) (is :: [Nat]).
(RecSubset record rs ss is, RecSubsetFCtx record f) =>
record f ss -> record f rs
rcast Record ts
r :: Record vs
type family RDeleteAll ss ts where
RDeleteAll '[] ts = ts
RDeleteAll (s ': ss) ts = RDeleteAll ss (RDelete s ts)
meltRow' :: forall proxy vs ts ss. (vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts,
Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs)
=> proxy ss
-> Record ts
-> [Record ("value" :-> CoRec ElField vs ': ss)]
meltRow' :: forall (proxy :: [(Symbol, *)] -> *) (vs :: [(Symbol, *)])
(ts :: [(Symbol, *)]) (ss :: [(Symbol, *)]).
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, Disjoint ss ts ~ 'True,
ts ≅ (vs ++ ss), ColumnHeaders vs, RowToColumn vs vs) =>
proxy ss
-> Record ts -> [Record (("value" :-> CoRec ElField vs) : ss)]
meltRow' proxy ss
_ = forall (vs :: [(Symbol, *)]) (ss :: [(Symbol, *)])
(ts :: [(Symbol, *)]).
(vs ⊆ ts, ss ⊆ ts, Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs) =>
Record ts -> [Record (("value" :-> CoRec ElField vs) : ss)]
meltAux
retroSnoc :: forall t ts. Record (t ': ts) -> Record (ts ++ '[t])
retroSnoc :: forall (t :: (Symbol, *)) (ts :: [(Symbol, *)]).
Record (t : ts) -> Record (ts ++ '[t])
retroSnoc (ElField r
x :& Rec ElField rs
xs) = forall (ss :: [(Symbol, *)]). Record ss -> Record (ss ++ '[t])
go Rec ElField rs
xs
where go :: Record ss -> Record (ss ++ '[t])
go :: forall (ss :: [(Symbol, *)]). Record ss -> Record (ss ++ '[t])
go Rec ElField ss
RNil = ElField r
x forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& forall {u} (a :: u -> *). Rec a '[]
RNil
go (ElField r
y :& Rec ElField rs
ys) = ElField r
y forall {u} (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& forall (ss :: [(Symbol, *)]). Record ss -> Record (ss ++ '[t])
go Rec ElField rs
ys
meltRow :: (vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts,
Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs)
=> proxy ss
-> Record ts
-> [Record (ss ++ '["value" :-> CoRec ElField vs])]
meltRow :: forall (vs :: [(Symbol, *)]) (ts :: [(Symbol, *)])
(ss :: [(Symbol, *)]) (proxy :: [(Symbol, *)] -> *).
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, Disjoint ss ts ~ 'True,
ts ≅ (vs ++ ss), ColumnHeaders vs, RowToColumn vs vs) =>
proxy ss
-> Record ts -> [Record (ss ++ '["value" :-> CoRec ElField vs])]
meltRow = (forall a b. (a -> b) -> [a] -> [b]
map forall (t :: (Symbol, *)) (ts :: [(Symbol, *)]).
Record (t : ts) -> Record (ts ++ '[t])
retroSnoc forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (proxy :: [(Symbol, *)] -> *) (vs :: [(Symbol, *)])
(ts :: [(Symbol, *)]) (ss :: [(Symbol, *)]).
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, Disjoint ss ts ~ 'True,
ts ≅ (vs ++ ss), ColumnHeaders vs, RowToColumn vs vs) =>
proxy ss
-> Record ts -> [Record (("value" :-> CoRec ElField vs) : ss)]
meltRow'
class HasLength (ts :: [k]) where
hasLength :: proxy ts -> Int
instance HasLength '[] where hasLength :: forall (proxy :: [k] -> *). proxy '[] -> Int
hasLength proxy '[]
_ = Int
0
instance forall t ts. HasLength ts => HasLength (t ': ts) where
hasLength :: forall (proxy :: [k] -> *). proxy (t : ts) -> Int
hasLength proxy (t : ts)
_ = Int
1 forall a. Num a => a -> a -> a
+ forall k (ts :: [k]) (proxy :: [k] -> *).
HasLength ts =>
proxy ts -> Int
hasLength (forall {k} (t :: k). Proxy t
Proxy :: Proxy ts)
melt :: forall vs ts ss proxy.
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, HasLength vs,
Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss),
ColumnHeaders vs, RowToColumn vs vs)
=> proxy ss
-> FrameRec ts
-> FrameRec (ss ++ '["value" :-> CoRec ElField vs])
melt :: forall (vs :: [(Symbol, *)]) (ts :: [(Symbol, *)])
(ss :: [(Symbol, *)]) (proxy :: [(Symbol, *)] -> *).
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, HasLength vs,
Disjoint ss ts ~ 'True, ts ≅ (vs ++ ss), ColumnHeaders vs,
RowToColumn vs vs) =>
proxy ss
-> FrameRec ts -> FrameRec (ss ++ '["value" :-> CoRec ElField vs])
melt proxy ss
p (Frame Int
n Int -> Record ts
v) = forall r. Int -> (Int -> r) -> Frame r
Frame (Int
nforall a. Num a => a -> a -> a
*Int
numVs) Int -> Record (ss ++ '["value" :-> CoRec ElField vs])
go
where numVs :: Int
numVs = forall k (ts :: [k]) (proxy :: [k] -> *).
HasLength ts =>
proxy ts -> Int
hasLength (forall {k} (t :: k). Proxy t
Proxy :: Proxy vs)
go :: Int -> Record (ss ++ '["value" :-> CoRec ElField vs])
go Int
i = let (Int
j,Int
k) = Int
i forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
numVs
in forall (vs :: [(Symbol, *)]) (ts :: [(Symbol, *)])
(ss :: [(Symbol, *)]) (proxy :: [(Symbol, *)] -> *).
(vs ⊆ ts, ss ⊆ ts, vs ~ RDeleteAll ss ts, Disjoint ss ts ~ 'True,
ts ≅ (vs ++ ss), ColumnHeaders vs, RowToColumn vs vs) =>
proxy ss
-> Record ts -> [Record (ss ++ '["value" :-> CoRec ElField vs])]
meltRow proxy ss
p (Int -> Record ts
v Int
j) forall a. [a] -> Int -> a
!! Int
k