rel8-1.0.0.0: src/Rel8/Schema/HTable/Label.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
{-# language ConstraintKinds #-}
{-# language DataKinds #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language MultiParamTypeClasses #-}
{-# language QuantifiedConstraints #-}
{-# language RankNTypes #-}
{-# language RecordWildCards #-}
{-# language ScopedTypeVariables #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}
module Rel8.Schema.HTable.Label
( HLabel, Label
, hlabel, hunlabel
)
where
-- base
import Data.Proxy ( Proxy( Proxy ) )
import GHC.TypeLits ( KnownSymbol, Symbol )
import Prelude
-- rel8
import Rel8.Kind.Labels ( SLabels( SCons ) )
import Rel8.Schema.HTable
( HTable
, hfield, htabulate, hspecs
)
import qualified Rel8.Schema.Kind as K
import Rel8.Schema.Spec ( Spec( Spec ), SSpec(..) )
import Rel8.FCF
import Rel8.Schema.HTable.MapTable
import GHC.Generics (Generic)
type HLabel :: Symbol -> K.HTable -> K.HTable
newtype HLabel label table context = HLabel (HMapTable (Label label) table context)
deriving stock Generic
deriving anyclass HTable
data Label :: Symbol -> Spec -> Exp Spec
type instance Eval (Label label ('Spec labels a)) = 'Spec (label : labels) a
instance KnownSymbol l => MapSpec (Label l) where
mapInfo = \case
SSpec {..} -> SSpec {labels = SCons Proxy labels, ..}
hlabel :: (HTable t, KnownSymbol label)
=> (forall labels a. ()
=> context ('Spec labels a)
-> context ('Spec (label ': labels) a))
-> t context
-> HLabel label t context
hlabel labeler a = HLabel $ htabulate $ \(HMapTableField field) ->
case hfield hspecs field of
SSpec {} -> labeler (hfield a field)
{-# INLINABLE hlabel #-}
hunlabel :: (HTable t, KnownSymbol label)
=> (forall labels a. ()
=> context ('Spec (label ': labels) a)
-> context ('Spec labels a))
-> HLabel label t context
-> t context
hunlabel unlabler (HLabel as) =
htabulate $ \field ->
case hfield hspecs field of
SSpec {} -> case hfield as (HMapTableField field) of
a -> unlabler a
{-# INLINABLE hunlabel #-}