{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} module SuperRecord.Field where import Data.Typeable import GHC.OverloadedLabels import GHC.TypeLits -- | Field named @l@ labels value of type @t@ adapted from the awesome /labels/ package. -- Example: @(#name := \"Chris\") :: (\"name\" := String)@ data label := value = KnownSymbol label => FldProxy label := !value deriving instance Typeable (:=) deriving instance Typeable (label := value) infix 6 := instance (Eq value) => Eq (label := value) where (_ := x) == (_ := y) = x == y {-# INLINE (==) #-} instance (Ord value) => Ord (label := value) where compare (_ := x) (_ := y) = x `compare` y {-# INLINE compare #-} instance (Show t) => Show (l := t) where showsPrec p (l := t) = showParen (p > 10) (showString ("#" ++ symbolVal l ++ " := " ++ show t)) -- | A proxy witness for a label. Very similar to 'Proxy', but needed to implement -- a non-orphan 'IsLabel' instance data FldProxy (t :: Symbol) = FldProxy deriving (Show, Read, Eq, Ord, Typeable) instance l ~ l' => IsLabel (l :: Symbol) (FldProxy l') where #if MIN_VERSION_base(4, 10, 0) fromLabel = FldProxy #else fromLabel _ = FldProxy #endif