wakame-0.1.0.0: src/Wakame/Row.hs
{-# LANGUAGE UndecidableInstances #-}
module Wakame.Row
( FIELD
-- * Keyed value type and function
, V (..)
, Keyed
, keyed
-- * Row type
, Row
, IsRow (..)
-- * Re-export from Data.SOP.NP
, 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)
-- | Kind of field
type FIELD = (Symbol, Type)
-- |
-- >>> V 3 :: V '("x", Int)
-- (x: 3)
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
-- * Helper functions
type Keyed k v = V '(k, v)
keyed :: KnownSymbol k => v -> Keyed k v
keyed = V
-- * Row type
type Row as = NP V (as :: [FIELD])
-- | Typeclass of converting from/to @Row@
class IsRow (a :: Type) where
type Of a :: [FIELD]
fromRow :: Row (Of a) -> a
toRow :: a -> Row (Of a)