module Data.Vinyl.Constraint
( (<:)(..)
, (:~:)
, (~=)
, RecAll
) where
import Data.Vinyl.Core
import Data.Vinyl.Witnesses
import Data.Vinyl.TyFun
import GHC.Prim (Constraint)
class (xs :: [k]) <: (ys :: [k]) where
cast :: Rec el f xs -> Rec el f ys
instance xs <: '[] where
cast _ = RNil
instance (y ∈ xs, xs <: ys) => xs <: (y ': ys) where
cast xs = ith (implicitly :: Elem y xs) xs :& cast xs
where
ith :: Elem r rs -> Rec el f rs -> f (el $ r)
ith Here (a :& _) = a
ith (There p) (_ :& as) = ith p as
type r1 :~: r2 = (r1 <: r2, r2 <: r1)
(~=) :: (Eq (Rec el f xs), xs :~: ys) => Rec el f xs -> Rec el f ys -> Bool
x ~= y = x == (cast y)
type family RecAll (el :: TyFun k l -> *) (f :: * -> *) (rs :: [k]) (c :: * -> Constraint) :: Constraint
type instance RecAll el f '[] c = ()
type instance RecAll el f (r ': rs) c = (c (f (el $ r)), RecAll el f rs c)