vinyl-utils-0.2.0.0: src/Data/Vinyl/Utils/Field.hs
{-|
Module : Data.Vinyl.Utils.Field
Copyright : (c) Marcin Mrotek, 2014
License : BSD3
Maintainer : marcin.jan.mrotek@gmail.com
Manipulation of constraints that apply to field labels (as opposed to actual types stored in the record).
-}
{-# LANGUAGE
ConstraintKinds
, DataKinds
, GADTs
, PolyKinds
, TypeFamilies
, TypeOperators
#-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Data.Vinyl.Utils.Field where
import Data.Proxy
import Data.Vinyl
import GHC.Exts
-- |Assert that all field labels in a given type list satisfy a given constraint.
type family FieldAll (rs :: [k]) (c :: k -> Constraint) :: Constraint where
FieldAll '[] c = ()
FieldAll (r ': rs) c = (c r, FieldAll rs c)
-- |An empty data type that reifies a constraint.
data DictProxy c a where
DictProxy :: c a => DictProxy c a
getProxy :: DictProxy c a -> Proxy a
-- ^Obtain a 'Proxy' from a 'DictProxy'
getProxy DictProxy = Proxy
reifyFieldConstraint :: FieldAll rs c => proxy c -> Rec Proxy rs -> Rec (DictProxy c) rs
-- ^Given a constraint that applies to all field labels and a dummy record, reify the constraint for all field labels.
reifyFieldConstraint _ RNil = RNil
reifyFieldConstraint c (Proxy :& ps) = DictProxy :& reifyFieldConstraint c ps