fcf-composite-0.1.1.0: src/Composite/Fcf.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Composite.Fcf
( FromCompositeS,
FromComposite,
ToCompositeS,
ToComposite,
Union,
Difference,
Intersection,
difference,
union,
intersection,
)
where
import Composite.Record
import Data.Kind
import Data.Vinyl
import Data.Vinyl.Lens
import Data.Vinyl.TypeLevel as V
import Fcf
import qualified Fcf.Data.MapC
import GHC.TypeLits
-- | Turn a single `s :-> a` into an `'(s, a)`
--
-- @since 0.1.0.0
data FromCompositeS :: Type -> Exp (Symbol, Type)
type instance Eval (FromCompositeS (s :-> x)) = '(s, x)
-- | Turn a list of `(s -> a)` into a `MapC s a`
--
-- @since 0.1.0.0
data FromComposite :: [Type] -> Exp (Fcf.Data.MapC.MapC Symbol Type)
type instance Eval (FromComposite x) = Eval (Fcf.Data.MapC.FromList =<< Fcf.Map FromCompositeS x)
-- | Turn a single `(s, a)` into a `s :-> a`
--
-- @since 0.1.0.0
data ToCompositeS :: (Symbol, Type) -> Exp Type
type instance Eval (ToCompositeS '(s, x)) = s :-> x
-- | Turn a `MapC s a` into a list of `(s :-> a)`
--
-- @since 0.1.0.0
data ToComposite :: Fcf.Data.MapC.MapC Symbol Type -> Exp [Type]
type instance Eval (ToComposite x) = Eval (Fcf.Map ToCompositeS =<< Fcf.Data.MapC.ToList x)
-- | Difference
--
-- @since 0.1.0.0
data Difference :: [Type] -> [Type] -> Exp [Type]
type instance Eval (Difference xs ys) = Eval (ToComposite =<< Fcf.Data.MapC.Difference (Eval (FromComposite xs)) (Eval (FromComposite ys)))
-- | Difference
--
-- @since 0.1.0.0
data Union :: [Type] -> [Type] -> Exp [Type]
type instance Eval (Union xs ys) = Eval (ToComposite =<< Fcf.Data.MapC.Union (Eval (FromComposite xs)) (Eval (FromComposite ys)))
-- | Intersection
--
-- @since 0.1.0.0
data Intersection :: [Type] -> [Type] -> Exp [Type]
type instance Eval (Intersection xs ys) = Eval (ToComposite =<< Fcf.Data.MapC.Intersection (Eval (FromComposite xs)) (Eval (FromComposite ys)))
-- | Take the difference of two records by casting to the result of `Difference`.
--
-- @since 0.1.1.0
difference ::
forall f xs ys zs.
( zs ~ Eval (Difference xs ys),
zs ⊆ (xs V.++ ys)
) =>
Rec f xs ->
Rec f ys ->
Rec f zs
difference x y = rcast @zs (x <+> y)
-- | Take the union of two records by casting to the result of `Union`.
--
-- @since 0.1.1.0
union ::
forall f xs ys zs.
( zs ~ Eval (Union xs ys),
zs ⊆ (xs V.++ ys)
) =>
Rec f xs ->
Rec f ys ->
Rec f zs
union x y = rcast @zs (x <+> y)
-- | Take the intersection of two records by casting to the result of `Intersection`.
--
-- @since 0.1.1.0
intersection ::
forall f xs ys zs.
( zs ~ Eval (Intersection xs ys),
zs ⊆ (xs V.++ ys)
) =>
Rec f xs ->
Rec f ys ->
Rec f zs
intersection x y = rcast @zs (x <+> y)