{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Data.OpenADT.VariantsF where
import Control.Arrow ( (+++) )
import Data.String ( IsString )
import Data.Row
import Data.Row.Variants
import Data.Row.Internal ( Unconstrained1 )
import Data.OpenADT.VarF
diversifyF
:: forall r' x r
. (ApplyRow x r .\/ ApplyRow x r' ≈ ApplyRow x (r .\/ r'))
=> VarF r x
-> VarF (r .\/ r') x
diversifyF = mapVarF $ diversify @(ApplyRow x r') @(ApplyRow x r)
trialF
:: (ApplyRow x r .- l ≈ ApplyRow x (r .- l), KnownSymbol l)
=> VarF r x
-> Label l
-> Either (ApplyRow x r .! l) (VarF (r .- l) x)
trialF v l = (id +++ VarF) (trial (unVarF v) l)
multiTrialF
:: forall u v x
. ( ApplyRow x v .\\ ApplyRow x u ≈ ApplyRow x (v .\\ u)
, AllUniqueLabels (ApplyRow x u)
, Forall (ApplyRow x (v .\\ u)) Unconstrained1
)
=> VarF v x
-> Either (VarF u x) (VarF (v .\\ u) x)
multiTrialF = (VarF +++ VarF) . multiTrial . unVarF
eraseF
:: forall c r x b
. Forall (ApplyRow x r) c
=> (forall a . c a => a -> b)
-> VarF r x
-> b
eraseF f = snd @String . eraseWithLabelsF @c f
eraseWithLabelsF
:: forall c r x s b
. (Forall (ApplyRow x r) c, IsString s)
=> (forall a . c a => a -> b)
-> VarF r x
-> (s, b)
eraseWithLabelsF f = eraseWithLabels @c f . unVarF
caseonF :: (Switch (ApplyRow x v) r y) => Rec r -> VarF v x -> y
caseonF r = caseon r . unVarF
switchF :: (Switch (ApplyRow x v) r y) => VarF v x -> Rec r -> y
switchF v = switch (unVarF v)