{-# LANGUAGE UndecidableInstances #-}
module Wakame.Row
( FIELD
, V (..)
, Keyed
, keyed
, Row
, IsRow (..)
, NP (..)
) where
import Prelude
import Data.Kind
import Data.Proxy
import Data.SOP.NP (NP (..))
import GHC.Generics
import GHC.TypeLits
import Wakame.Utils (Fst, Snd)
type FIELD = (Symbol, Type)
newtype V (p :: FIELD) = V { unV :: Snd p }
instance (KnownSymbol (Fst p), Show (Snd p)) => Show (V p) where
show (V x) = "(" <> symbolVal (Proxy @(Fst p)) <> ": " <> show x <> ")"
instance (KnownSymbol (Fst p), Eq (Snd p)) => Eq (V p) where
(==) (V x) (V y) = x == y
instance Generic (V '(k, v)) where
type Rep (V '(k, v)) = S1 ('MetaSel ('Just k) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 v)
from (V x) = M1 (K1 x)
to (M1 (K1 x)) = V x
type Keyed k v = V '(k, v)
keyed :: KnownSymbol k => v -> Keyed k v
keyed = V
type Row as = NP V (as :: [FIELD])
class IsRow (a :: Type) where
type Of a :: [FIELD]
fromRow :: Row (Of a) -> a
toRow :: a -> Row (Of a)