{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ConstraintKinds,
DataKinds,
EmptyCase,
FlexibleContexts,
FlexibleInstances,
FunctionalDependencies,
KindSignatures,
GADTs,
MultiParamTypeClasses,
PatternSynonyms,
PolyKinds,
ScopedTypeVariables,
TypeFamilies,
TypeOperators,
UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Frames.Rec where
import Data.Vinyl hiding (rget)
import qualified Data.Vinyl as V
import Data.Vinyl.Functor (Const(..), Compose(..), (:.))
import Data.Vinyl.Class.Method (PayloadType)
import Frames.Col
import GHC.TypeLits (KnownSymbol)
type Record = FieldRec
(&:) :: KnownSymbol s => a -> Record rs -> Record (s :-> a ': rs)
x &: xs = Field x :& xs
infixr 5 &:
type family RecordColumns t where
RecordColumns (Record ts) = ts
recUncons :: Record (s :-> a ': rs) -> (a, Record rs)
recUncons (Field x :& xs) = (x, xs)
recMaybe :: Rec (Maybe :. ElField) cs -> Maybe (Record cs)
recMaybe = rtraverse getCompose
{-# INLINE recMaybe #-}
showFields :: (RecMapMethod Show ElField ts, RecordToList ts)
=> Record ts -> [String]
showFields = recordToList . rmapMethod @Show aux
where aux :: (Show (PayloadType ElField a)) => ElField a -> Const String a
aux (Field x) = Const (show x)
{-# INLINABLE showFields #-}
rgetField :: forall t s a rs. (t ~ '(s,a), t ∈ rs) => Record rs -> a
rgetField = getField . V.rget @t
{-# INLINE rgetField #-}
rputField :: forall t s a rs. (t ~ '(s,a), t ∈ rs, KnownSymbol s)
=> a -> Record rs -> Record rs
rputField = V.rput @t . Field
{-# INLINE rputField #-}