{-# LANGUAGE CPP #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DerivingVia #-}
{-# OPTIONS_GHC -Wno-x-partial #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module Stock.Derive
(
Datatype(..)
, Constructor(..)
, Synth
, runSynth
, synthTc
, liftTc
, field
, fresh
, castInto
, classDict
, classDictWith
, classMethod
, productCon
, matchSOP
, injectSOP
, fromProduct
, toProduct
, pureFields
, cpureFields
, mapFields
, cmapFields
, zipFields
, czipFields
, foldlFields
, cfoldlFields
, traverseFields
, ctraverseFields
, Deriver(..)
, DeriveStock(..)
, Deriver1(..)
, DeriveStock1(..)
, Deriver2(..)
, DeriveStock2(..)
) where
import GHC.Plugins
import GHC.Tc.Plugin (TcPluginM, newWanted, unsafeTcPluginTcM, tcLookupId)
import GHC.Tc.Types.Constraint (Ct, mkNonCanonical, ctEvExpr)
#if MIN_VERSION_ghc(9,12,0)
import GHC.Tc.Types.CtLoc (CtLoc)
#else
import GHC.Tc.Types.Constraint (CtLoc)
#endif
import GHC.Tc.Types.Evidence (EvTerm(EvExpr))
import GHC.Core.Predicate (mkClassPred)
import GHC.Core.Class (Class, classMethods, classOpItems)
import GHC.Types.Fixity (Fixity)
import Control.Monad (forM, foldM)
import Stock.Trans (ReaderT(..), WriterT(..))
import qualified Data.Kind as K
data Datatype = Datatype
{ Datatype -> Type
dtVia :: Type
, Datatype -> Coercion
dtUnwrap :: Coercion
, Datatype -> Type
dtType :: Type
, Datatype -> [Constructor]
dtCons :: [Constructor]
}
data Constructor = Constructor
{ Constructor -> DataCon
conDataCon :: DataCon
, Constructor -> [Type]
conFields :: [Type]
, Constructor -> Fixity
conFixity :: Fixity
, Constructor -> Maybe [FieldLabel]
conLabels :: Maybe [FieldLabel]
, Constructor -> [Coercion]
conFieldCos :: [Coercion]
}
newtype Synth a = Synth (CtLoc -> TcPluginM (a, [Ct]))
deriving ((forall a b. (a -> b) -> Synth a -> Synth b)
-> (forall a b. a -> Synth b -> Synth a) -> Functor Synth
forall a b. a -> Synth b -> Synth a
forall a b. (a -> b) -> Synth a -> Synth b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Synth a -> Synth b
fmap :: forall a b. (a -> b) -> Synth a -> Synth b
$c<$ :: forall a b. a -> Synth b -> Synth a
<$ :: forall a b. a -> Synth b -> Synth a
Functor, Functor Synth
Functor Synth =>
(forall a. a -> Synth a)
-> (forall a b. Synth (a -> b) -> Synth a -> Synth b)
-> (forall a b c. (a -> b -> c) -> Synth a -> Synth b -> Synth c)
-> (forall a b. Synth a -> Synth b -> Synth b)
-> (forall a b. Synth a -> Synth b -> Synth a)
-> Applicative Synth
forall a. a -> Synth a
forall a b. Synth a -> Synth b -> Synth a
forall a b. Synth a -> Synth b -> Synth b
forall a b. Synth (a -> b) -> Synth a -> Synth b
forall a b c. (a -> b -> c) -> Synth a -> Synth b -> Synth c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> Synth a
pure :: forall a. a -> Synth a
$c<*> :: forall a b. Synth (a -> b) -> Synth a -> Synth b
<*> :: forall a b. Synth (a -> b) -> Synth a -> Synth b
$cliftA2 :: forall a b c. (a -> b -> c) -> Synth a -> Synth b -> Synth c
liftA2 :: forall a b c. (a -> b -> c) -> Synth a -> Synth b -> Synth c
$c*> :: forall a b. Synth a -> Synth b -> Synth b
*> :: forall a b. Synth a -> Synth b -> Synth b
$c<* :: forall a b. Synth a -> Synth b -> Synth a
<* :: forall a b. Synth a -> Synth b -> Synth a
Applicative, Applicative Synth
Applicative Synth =>
(forall a b. Synth a -> (a -> Synth b) -> Synth b)
-> (forall a b. Synth a -> Synth b -> Synth b)
-> (forall a. a -> Synth a)
-> Monad Synth
forall a. a -> Synth a
forall a b. Synth a -> Synth b -> Synth b
forall a b. Synth a -> (a -> Synth b) -> Synth b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b. Synth a -> (a -> Synth b) -> Synth b
>>= :: forall a b. Synth a -> (a -> Synth b) -> Synth b
$c>> :: forall a b. Synth a -> Synth b -> Synth b
>> :: forall a b. Synth a -> Synth b -> Synth b
$creturn :: forall a. a -> Synth a
return :: forall a. a -> Synth a
Monad)
via ReaderT CtLoc (WriterT [Ct] TcPluginM)
runSynth :: CtLoc -> Synth a -> TcPluginM (a, [Ct])
runSynth :: forall a. CtLoc -> Synth a -> TcPluginM (a, [Ct])
runSynth CtLoc
loc (Synth CtLoc -> TcPluginM (a, [Ct])
g) = CtLoc -> TcPluginM (a, [Ct])
g CtLoc
loc
synthTc :: (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
synthTc :: forall a. (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
synthTc = (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
forall a. (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
Synth
liftTc :: TcPluginM a -> Synth a
liftTc :: forall a. TcPluginM a -> Synth a
liftTc TcPluginM a
m = (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
forall a. (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
Synth \CtLoc
_ -> do a
a <- TcPluginM a
m; (a, [Ct]) -> TcPluginM (a, [Ct])
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, [])
field :: Class -> Type -> Synth CoreExpr
field :: Class -> Type -> Synth CoreExpr
field Class
cls Type
ty = (CtLoc -> TcPluginM (CoreExpr, [Ct])) -> Synth CoreExpr
forall a. (CtLoc -> TcPluginM (a, [Ct])) -> Synth a
Synth \CtLoc
loc -> do
CtEvidence
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Class -> [Type] -> Type
mkClassPred Class
cls [Type
ty])
(CoreExpr, [Ct]) -> TcPluginM (CoreExpr, [Ct])
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev, [CtEvidence -> Ct
mkNonCanonical CtEvidence
ev])
fresh :: Type -> String -> Synth Id
fresh :: Type -> String -> Synth Id
fresh Type
ty String
s = TcPluginM Id -> Synth Id
forall a. TcPluginM a -> Synth a
liftTc (TcPluginM Id -> Synth Id) -> TcPluginM Id -> Synth Id
forall a b. (a -> b) -> a -> b
$ do
Unique
u <- TcM Unique -> TcPluginM Unique
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM TcM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
Id -> TcPluginM Id
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HasDebugCallStack => Name -> Type -> Type -> Id
Name -> Type -> Type -> Id
mkLocalId (Unique -> OccName -> Name
mkSystemName Unique
u (String -> OccName
mkVarOcc String
s)) Type
manyDataConTy Type
ty)
classMethod :: String -> Class -> Id
classMethod :: String -> Class -> Id
classMethod String
name Class
cls =
case (Id -> Bool) -> [Id] -> [Id]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
name) (String -> Bool) -> (Id -> String) -> Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccName -> String
occNameString (OccName -> String) -> (Id -> OccName) -> Id -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> OccName
forall name. HasOccName name => name -> OccName
occName) (Class -> [Id]
classMethods Class
cls) of
(Id
m : [Id]
_) -> Id
m
[] -> String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"stock: classMethod: no method" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Class -> SDoc
forall a. Outputable a => a -> SDoc
ppr Class
cls)
classDict :: Class -> Type -> [CoreExpr] -> EvTerm
classDict :: Class -> Type -> [CoreExpr] -> EvTerm
classDict Class
cls Type
ty [CoreExpr]
methods =
CoreExpr -> EvTerm
EvExpr (CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var (DataCon -> Id
dataConWorkId (Class -> DataCon
classDataCon Class
cls))) (Type -> CoreExpr
forall b. Type -> Expr b
Type Type
ty CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: [CoreExpr]
methods))
classDictWith :: Class -> Type -> [CoreExpr] -> [(Int, CoreExpr)] -> Synth EvTerm
classDictWith :: Class -> Type -> [CoreExpr] -> [(Int, CoreExpr)] -> Synth EvTerm
classDictWith Class
cls Type
ty [CoreExpr]
supers [(Int, CoreExpr)]
overrides = do
Id
dvar <- Type -> String -> Synth Id
fresh (Class -> [Type] -> Type
mkClassPred Class
cls [Type
ty]) String
"dict"
[CoreExpr]
methods <- [(Int, Id)] -> ((Int, Id) -> Synth CoreExpr) -> Synth [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM ([Int] -> [Id] -> [(Int, Id)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] (Class -> [Id]
classMethods Class
cls)) \(Int
i, Id
_) ->
case Int -> [(Int, CoreExpr)] -> Maybe CoreExpr
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
i [(Int, CoreExpr)]
overrides of
Just CoreExpr
e -> CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CoreExpr
e
Maybe CoreExpr
Nothing -> case (Id, DefMethInfo) -> DefMethInfo
forall a b. (a, b) -> b
snd (Class -> [(Id, DefMethInfo)]
classOpItems Class
cls [(Id, DefMethInfo)] -> Int -> (Id, DefMethInfo)
forall a. HasCallStack => [a] -> Int -> a
!! Int
i) of
Just (Name
nm, DefMethSpec Type
_) -> do Id
dm <- TcPluginM Id -> Synth Id
forall a. TcPluginM a -> Synth a
liftTc (Name -> TcPluginM Id
tcLookupId Name
nm)
CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
dm) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
ty, Id -> CoreExpr
forall b. Id -> Expr b
Var Id
dvar])
DefMethInfo
Nothing -> String -> Synth CoreExpr
forall a. HasCallStack => String -> a
error String
"stock: classDictWith: method has no default and no override"
let EvExpr CoreExpr
con = Class -> Type -> [CoreExpr] -> EvTerm
classDict Class
cls Type
ty ([CoreExpr]
supers [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr]
methods)
EvTerm -> Synth EvTerm
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CoreExpr -> EvTerm
EvExpr (Bind Id -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let ([(Id, CoreExpr)] -> Bind Id
forall b. [(b, Expr b)] -> Bind b
Rec [(Id
dvar, CoreExpr
con)]) (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
dvar)))
productCon :: Datatype -> Constructor
productCon :: Datatype -> Constructor
productCon = [Constructor] -> Constructor
forall a. HasCallStack => [a] -> a
head ([Constructor] -> Constructor)
-> (Datatype -> [Constructor]) -> Datatype -> Constructor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Datatype -> [Constructor]
dtCons
matchSOP :: Datatype -> Type -> CoreExpr
-> (Int -> Constructor -> [CoreExpr] -> Synth CoreExpr) -> Synth CoreExpr
matchSOP :: Datatype
-> Type
-> CoreExpr
-> (Int -> Constructor -> [CoreExpr] -> Synth CoreExpr)
-> Synth CoreExpr
matchSOP Datatype
dt Type
resTy CoreExpr
v Int -> Constructor -> [CoreExpr] -> Synth CoreExpr
k = do
Id
cb <- Type -> String -> Synth Id
fresh (Datatype -> Type
dtType Datatype
dt) String
"s"
[Alt Id]
alts <- [(Int, Constructor)]
-> ((Int, Constructor) -> Synth (Alt Id)) -> Synth [Alt Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM ([Int] -> [Constructor] -> [(Int, Constructor)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] (Datatype -> [Constructor]
dtCons Datatype
dt)) \(Int
i, Constructor
c) -> do
[Id]
xs <- (Coercion -> Synth Id) -> [Coercion] -> Synth [Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\Coercion
co -> Type -> String -> Synth Id
fresh (Coercion -> Type
coercionLKind Coercion
co) String
"x") (Constructor -> [Coercion]
conFieldCos Constructor
c)
CoreExpr
body <- Int -> Constructor -> [CoreExpr] -> Synth CoreExpr
k Int
i Constructor
c ((CoreExpr -> Coercion -> CoreExpr)
-> [CoreExpr] -> [Coercion] -> [CoreExpr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith CoreExpr -> Coercion -> CoreExpr
castInto ((Id -> CoreExpr) -> [Id] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Id -> CoreExpr
forall b. Id -> Expr b
Var [Id]
xs) (Constructor -> [Coercion]
conFieldCos Constructor
c))
Alt Id -> Synth (Alt Id)
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AltCon -> [Id] -> CoreExpr -> Alt Id
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt (DataCon -> AltCon
DataAlt (Constructor -> DataCon
conDataCon Constructor
c)) [Id]
xs CoreExpr
body)
CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CoreExpr -> Id -> Type -> [Alt Id] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
v (Datatype -> Coercion
dtUnwrap Datatype
dt)) Id
cb Type
resTy [Alt Id]
alts)
castInto :: CoreExpr -> Coercion -> CoreExpr
castInto :: CoreExpr -> Coercion -> CoreExpr
castInto CoreExpr
e Coercion
co = if Coercion -> Bool
isReflCo Coercion
co then CoreExpr
e else CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
e Coercion
co
injectSOP :: Datatype -> Constructor -> [CoreExpr] -> CoreExpr
injectSOP :: Datatype -> Constructor -> [CoreExpr] -> CoreExpr
injectSOP Datatype
dt Constructor
c [CoreExpr]
es =
CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast (DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps (Constructor -> DataCon
conDataCon Constructor
c) ((Type -> CoreExpr) -> [Type] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Type -> CoreExpr
forall b. Type -> Expr b
Type (HasDebugCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs (Datatype -> Type
dtType Datatype
dt)) [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr]
es'))
(Coercion -> Coercion
mkSymCo (Datatype -> Coercion
dtUnwrap Datatype
dt))
where
es' :: [CoreExpr]
es' = (CoreExpr -> Coercion -> CoreExpr)
-> [CoreExpr] -> [Coercion] -> [CoreExpr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\CoreExpr
e Coercion
co -> CoreExpr -> Coercion -> CoreExpr
castInto CoreExpr
e (Coercion -> Coercion
mkSymCo Coercion
co)) [CoreExpr]
es (Constructor -> [Coercion]
conFieldCos Constructor
c)
fromProduct :: Datatype -> Type -> CoreExpr -> ([CoreExpr] -> Synth CoreExpr)
-> Synth CoreExpr
fromProduct :: Datatype
-> Type
-> CoreExpr
-> ([CoreExpr] -> Synth CoreExpr)
-> Synth CoreExpr
fromProduct Datatype
dt Type
resTy CoreExpr
v [CoreExpr] -> Synth CoreExpr
k = Datatype
-> Type
-> CoreExpr
-> (Int -> Constructor -> [CoreExpr] -> Synth CoreExpr)
-> Synth CoreExpr
matchSOP Datatype
dt Type
resTy CoreExpr
v \Int
_ Constructor
_ [CoreExpr]
fields -> [CoreExpr] -> Synth CoreExpr
k [CoreExpr]
fields
toProduct :: Datatype -> [CoreExpr] -> CoreExpr
toProduct :: Datatype -> [CoreExpr] -> CoreExpr
toProduct Datatype
dt = Datatype -> Constructor -> [CoreExpr] -> CoreExpr
injectSOP Datatype
dt (Datatype -> Constructor
productCon Datatype
dt)
pureFields :: (Type -> Synth a) -> Constructor -> Synth [a]
pureFields :: forall a. (Type -> Synth a) -> Constructor -> Synth [a]
pureFields Type -> Synth a
k Constructor
con = (Type -> Synth a) -> [Type] -> Synth [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Synth a
k (Constructor -> [Type]
conFields Constructor
con)
cpureFields :: Class -> (Type -> CoreExpr -> CoreExpr) -> Constructor -> Synth [CoreExpr]
cpureFields :: Class
-> (Type -> CoreExpr -> CoreExpr)
-> Constructor
-> Synth [CoreExpr]
cpureFields Class
cls Type -> CoreExpr -> CoreExpr
k = (Type -> Synth CoreExpr) -> Constructor -> Synth [CoreExpr]
forall a. (Type -> Synth a) -> Constructor -> Synth [a]
pureFields \Type
ft -> do CoreExpr
d <- Class -> Type -> Synth CoreExpr
field Class
cls Type
ft; CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> CoreExpr -> CoreExpr
k Type
ft CoreExpr
d)
mapFields :: (Type -> CoreExpr -> Synth a) -> Constructor -> [CoreExpr] -> Synth [a]
mapFields :: forall a.
(Type -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> Synth [a]
mapFields Type -> CoreExpr -> Synth a
k Constructor
con [CoreExpr]
xs = [Synth a] -> Synth [a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((Type -> CoreExpr -> Synth a) -> [Type] -> [CoreExpr] -> [Synth a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> CoreExpr -> Synth a
k (Constructor -> [Type]
conFields Constructor
con) [CoreExpr]
xs)
cmapFields :: Class -> (Type -> CoreExpr -> CoreExpr -> CoreExpr) -> Constructor -> [CoreExpr] -> Synth [CoreExpr]
cmapFields :: Class
-> (Type -> CoreExpr -> CoreExpr -> CoreExpr)
-> Constructor
-> [CoreExpr]
-> Synth [CoreExpr]
cmapFields Class
cls Type -> CoreExpr -> CoreExpr -> CoreExpr
k = (Type -> CoreExpr -> Synth CoreExpr)
-> Constructor -> [CoreExpr] -> Synth [CoreExpr]
forall a.
(Type -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> Synth [a]
mapFields \Type
ft CoreExpr
x -> do CoreExpr
d <- Class -> Type -> Synth CoreExpr
field Class
cls Type
ft; CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> CoreExpr -> CoreExpr -> CoreExpr
k Type
ft CoreExpr
d CoreExpr
x)
zipFields :: (Type -> CoreExpr -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> [CoreExpr] -> Synth [a]
zipFields :: forall a.
(Type -> CoreExpr -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> [CoreExpr] -> Synth [a]
zipFields Type -> CoreExpr -> CoreExpr -> Synth a
k Constructor
con [CoreExpr]
xs [CoreExpr]
ys = [Synth a] -> Synth [a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((Type -> CoreExpr -> CoreExpr -> Synth a)
-> [Type] -> [CoreExpr] -> [CoreExpr] -> [Synth a]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 Type -> CoreExpr -> CoreExpr -> Synth a
k (Constructor -> [Type]
conFields Constructor
con) [CoreExpr]
xs [CoreExpr]
ys)
czipFields :: Class -> (Type -> CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr)
-> Constructor -> [CoreExpr] -> [CoreExpr] -> Synth [CoreExpr]
czipFields :: Class
-> (Type -> CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr)
-> Constructor
-> [CoreExpr]
-> [CoreExpr]
-> Synth [CoreExpr]
czipFields Class
cls Type -> CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
k = (Type -> CoreExpr -> CoreExpr -> Synth CoreExpr)
-> Constructor -> [CoreExpr] -> [CoreExpr] -> Synth [CoreExpr]
forall a.
(Type -> CoreExpr -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> [CoreExpr] -> Synth [a]
zipFields \Type
ft CoreExpr
x CoreExpr
y -> do CoreExpr
d <- Class -> Type -> Synth CoreExpr
field Class
cls Type
ft; CoreExpr -> Synth CoreExpr
forall a. a -> Synth a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
k Type
ft CoreExpr
d CoreExpr
x CoreExpr
y)
foldlFields :: (a -> Type -> CoreExpr -> Synth a) -> a -> Constructor -> [CoreExpr] -> Synth a
foldlFields :: forall a.
(a -> Type -> CoreExpr -> Synth a)
-> a -> Constructor -> [CoreExpr] -> Synth a
foldlFields a -> Type -> CoreExpr -> Synth a
step a
z Constructor
con [CoreExpr]
fields =
(a -> (Type, CoreExpr) -> Synth a)
-> a -> [(Type, CoreExpr)] -> Synth a
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (\a
acc (Type
ft, CoreExpr
e) -> a -> Type -> CoreExpr -> Synth a
step a
acc Type
ft CoreExpr
e) a
z ([Type] -> [CoreExpr] -> [(Type, CoreExpr)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Constructor -> [Type]
conFields Constructor
con) [CoreExpr]
fields)
cfoldlFields :: Class
-> (CoreExpr -> Type -> CoreExpr -> CoreExpr -> Synth CoreExpr)
-> CoreExpr
-> Constructor -> [CoreExpr] -> Synth CoreExpr
cfoldlFields :: Class
-> (CoreExpr -> Type -> CoreExpr -> CoreExpr -> Synth CoreExpr)
-> CoreExpr
-> Constructor
-> [CoreExpr]
-> Synth CoreExpr
cfoldlFields Class
cls CoreExpr -> Type -> CoreExpr -> CoreExpr -> Synth CoreExpr
step =
(CoreExpr -> Type -> CoreExpr -> Synth CoreExpr)
-> CoreExpr -> Constructor -> [CoreExpr] -> Synth CoreExpr
forall a.
(a -> Type -> CoreExpr -> Synth a)
-> a -> Constructor -> [CoreExpr] -> Synth a
foldlFields \CoreExpr
acc Type
ft CoreExpr
e -> do CoreExpr
d <- Class -> Type -> Synth CoreExpr
field Class
cls Type
ft; CoreExpr -> Type -> CoreExpr -> CoreExpr -> Synth CoreExpr
step CoreExpr
acc Type
ft CoreExpr
d CoreExpr
e
traverseFields :: (Type -> CoreExpr -> Synth a) -> Constructor -> [CoreExpr] -> Synth [a]
traverseFields :: forall a.
(Type -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> Synth [a]
traverseFields Type -> CoreExpr -> Synth a
k Constructor
con [CoreExpr]
xs = [Synth a] -> Synth [a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((Type -> CoreExpr -> Synth a) -> [Type] -> [CoreExpr] -> [Synth a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> CoreExpr -> Synth a
k (Constructor -> [Type]
conFields Constructor
con) [CoreExpr]
xs)
ctraverseFields :: Class
-> (Type -> CoreExpr -> CoreExpr -> Synth CoreExpr)
-> Constructor -> [CoreExpr] -> Synth [CoreExpr]
ctraverseFields :: Class
-> (Type -> CoreExpr -> CoreExpr -> Synth CoreExpr)
-> Constructor
-> [CoreExpr]
-> Synth [CoreExpr]
ctraverseFields Class
cls Type -> CoreExpr -> CoreExpr -> Synth CoreExpr
k = (Type -> CoreExpr -> Synth CoreExpr)
-> Constructor -> [CoreExpr] -> Synth [CoreExpr]
forall a.
(Type -> CoreExpr -> Synth a)
-> Constructor -> [CoreExpr] -> Synth [a]
traverseFields \Type
ft CoreExpr
e -> do CoreExpr
d <- Class -> Type -> Synth CoreExpr
field Class
cls Type
ft; Type -> CoreExpr -> CoreExpr -> Synth CoreExpr
k Type
ft CoreExpr
d CoreExpr
e
newtype Deriver = Deriver { Deriver -> Class -> Datatype -> Synth EvTerm
runDeriver :: Class -> Datatype -> Synth EvTerm }
class DeriveStock (cls :: K.Type -> K.Constraint) where
deriveStock :: Deriver
newtype Deriver1 = Deriver1
{ Deriver1
-> Class
-> CtLoc
-> Type
-> Type
-> TcPluginM (Maybe (EvTerm, [Ct]))
runDeriver1 :: Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct])) }
class DeriveStock1 (cls :: (K.Type -> K.Type) -> K.Constraint) where
deriveStock1 :: Deriver1
newtype Deriver2 = Deriver2
{ Deriver2
-> Class
-> CtLoc
-> Type
-> Type
-> TcPluginM (Maybe (EvTerm, [Ct]))
runDeriver2 :: Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct])) }
class DeriveStock2 (cls :: (K.Type -> K.Type -> K.Type) -> K.Constraint) where
deriveStock2 :: Deriver2