{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Language.Haskell.TTH.LetRec (
letrecE,
letrecH,
typedLetrecE,
typedLetrecH,
) where
import Control.Monad.Fix (MonadFix)
import Data.GADT.Compare (GCompare)
import Data.Some (Some (..))
import Language.Haskell.TH.CodeT (CodeT, unTypeCodeT)
import Language.Haskell.TH.Syntax (Code, Quote, unTypeCode, unsafeCodeCoerce)
import qualified Language.Haskell.TH.LetRec as TH.LetRec
letrecE
:: forall q tag r a. (Ord tag, Quote q, MonadFix q)
=> (forall. tag -> String)
-> (forall m. Monad m => (tag -> m (Code q a)) -> (tag -> m (Code q a)))
-> (forall m. Monad m => (tag -> m (Code q a)) -> m (Code q r))
-> Code q r
letrecE :: forall (q :: * -> *) tag r a.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r))
-> Code q r
letrecE tag -> String
nameOf forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a)
bindf forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r)
exprf = q Exp -> Code q r
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q r) -> q Exp -> Code q r
forall a b. (a -> b) -> a -> b
$ (tag -> String)
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
forall (q :: * -> *) tag.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
TH.LetRec.letrecE
tag -> String
nameOf
(\tag -> m (q Exp)
recf tag
tag -> Code q a -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q a -> q Exp) -> m (Code q a) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (tag -> m (Code q a)) -> tag -> m (Code q a)
forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a)
bindf (\tag
tag' -> q Exp -> Code q a
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q a) -> m (q Exp) -> m (Code q a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> tag -> m (q Exp)
recf tag
tag') tag
tag)
(\tag -> m (q Exp)
recf -> Code q r -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q r -> q Exp) -> m (Code q r) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (tag -> m (Code q a)) -> m (Code q r)
forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r)
exprf (\tag
tag' -> q Exp -> Code q a
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q a) -> m (q Exp) -> m (Code q a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> tag -> m (q Exp)
recf tag
tag'))
typedLetrecE
:: forall q tag r a. (Ord tag, Quote q, MonadFix q)
=> (forall. tag -> String)
-> CodeT q a
-> (forall m. Monad m => (tag -> m (Code q a)) -> (tag -> m (Code q a)))
-> (forall m. Monad m => (tag -> m (Code q a)) -> m (Code q r))
-> Code q r
typedLetrecE :: forall (q :: * -> *) tag r a.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> CodeT q a
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r))
-> Code q r
typedLetrecE tag -> String
nameOf CodeT q a
typeOf forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a)
bindf forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r)
exprf = q Exp -> Code q r
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q r) -> q Exp -> Code q r
forall a b. (a -> b) -> a -> b
$ (tag -> String)
-> (tag -> Maybe (q Type))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
forall (q :: * -> *) tag.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> (tag -> Maybe (q Type))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
TH.LetRec.typedLetrecE
tag -> String
nameOf
(\tag
_ -> q Type -> Maybe (q Type)
forall a. a -> Maybe a
Just (CodeT q a -> q Type
forall {k} (m :: * -> *) (a :: k). CodeT m a -> m Type
unTypeCodeT CodeT q a
typeOf))
(\tag -> m (q Exp)
recf tag
tag -> Code q a -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q a -> q Exp) -> m (Code q a) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (tag -> m (Code q a)) -> tag -> m (Code q a)
forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> tag -> m (Code q a)
bindf (\tag
tag' -> q Exp -> Code q a
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q a) -> m (q Exp) -> m (Code q a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> tag -> m (q Exp)
recf tag
tag') tag
tag)
(\tag -> m (q Exp)
recf -> Code q r -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q r -> q Exp) -> m (Code q r) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (tag -> m (Code q a)) -> m (Code q r)
forall (m :: * -> *).
Monad m =>
(tag -> m (Code q a)) -> m (Code q r)
exprf (\tag
tag' -> q Exp -> Code q a
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q a) -> m (q Exp) -> m (Code q a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> tag -> m (q Exp)
recf tag
tag'))
letrecH
:: forall q tag r. (GCompare tag, Quote q, MonadFix q)
=> (forall x. tag x -> String)
-> (forall m y. Monad m => (forall x. tag x -> m (Code q x)) -> (tag y -> m (Code q y)))
-> (forall m. Monad m => (forall x. tag x -> m (Code q x)) -> m (Code q r))
-> Code q r
letrecH :: forall (q :: * -> *) (tag :: * -> *) r.
(GCompare tag, Quote q, MonadFix q) =>
(forall x. tag x -> String)
-> (forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y))
-> (forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r))
-> Code q r
letrecH forall x. tag x -> String
nameOf forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y)
bindf forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r)
exprf = q Exp -> Code q r
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q r) -> q Exp -> Code q r
forall a b. (a -> b) -> a -> b
$ (Some tag -> String)
-> (forall (m :: * -> *).
Monad m =>
(Some tag -> m (q Exp)) -> Some tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(Some tag -> m (q Exp)) -> m (q Exp))
-> q Exp
forall (q :: * -> *) tag.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
TH.LetRec.letrecE
(\(Some tag a
tag) -> tag a -> String
forall x. tag x -> String
nameOf tag a
tag)
(\Some tag -> m (q Exp)
recf (Some tag a
tag) -> Code q a -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q a -> q Exp) -> m (Code q a) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall x. tag x -> m (Code q x)) -> tag a -> m (Code q a)
forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y)
bindf (\tag x
tag' -> q Exp -> Code q x
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q x) -> m (q Exp) -> m (Code q x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Some tag -> m (q Exp)
recf (tag x -> Some tag
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some tag x
tag')) tag a
tag)
(\Some tag -> m (q Exp)
recf -> Code q r -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q r -> q Exp) -> m (Code q r) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall x. tag x -> m (Code q x)) -> m (Code q r)
forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r)
exprf (\tag x
tag' -> q Exp -> Code q x
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q x) -> m (q Exp) -> m (Code q x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Some tag -> m (q Exp)
recf (tag x -> Some tag
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some tag x
tag')))
typedLetrecH
:: forall q tag r. (GCompare tag, Quote q, MonadFix q)
=> (forall x. tag x -> String)
-> (forall x. tag x -> CodeT q x)
-> (forall m y. Monad m => (forall x. tag x -> m (Code q x)) -> (tag y -> m (Code q y)))
-> (forall m. Monad m => (forall x. tag x -> m (Code q x)) -> m (Code q r))
-> Code q r
typedLetrecH :: forall (q :: * -> *) (tag :: * -> *) r.
(GCompare tag, Quote q, MonadFix q) =>
(forall x. tag x -> String)
-> (forall x. tag x -> CodeT q x)
-> (forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y))
-> (forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r))
-> Code q r
typedLetrecH forall x. tag x -> String
nameOf forall x. tag x -> CodeT q x
typeOf forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y)
bindf forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r)
exprf = q Exp -> Code q r
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q r) -> q Exp -> Code q r
forall a b. (a -> b) -> a -> b
$ (Some tag -> String)
-> (Some tag -> Maybe (q Type))
-> (forall (m :: * -> *).
Monad m =>
(Some tag -> m (q Exp)) -> Some tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(Some tag -> m (q Exp)) -> m (q Exp))
-> q Exp
forall (q :: * -> *) tag.
(Ord tag, Quote q, MonadFix q) =>
(tag -> String)
-> (tag -> Maybe (q Type))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> tag -> m (q Exp))
-> (forall (m :: * -> *).
Monad m =>
(tag -> m (q Exp)) -> m (q Exp))
-> q Exp
TH.LetRec.typedLetrecE
(\(Some tag a
tag) -> tag a -> String
forall x. tag x -> String
nameOf tag a
tag)
(\(Some tag a
tag) -> q Type -> Maybe (q Type)
forall a. a -> Maybe a
Just (CodeT q a -> q Type
forall {k} (m :: * -> *) (a :: k). CodeT m a -> m Type
unTypeCodeT (tag a -> CodeT q a
forall x. tag x -> CodeT q x
typeOf tag a
tag)))
(\Some tag -> m (q Exp)
recf (Some tag a
tag) -> Code q a -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q a -> q Exp) -> m (Code q a) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall x. tag x -> m (Code q x)) -> tag a -> m (Code q a)
forall (m :: * -> *) y.
Monad m =>
(forall x. tag x -> m (Code q x)) -> tag y -> m (Code q y)
bindf (\tag x
tag' -> q Exp -> Code q x
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q x) -> m (q Exp) -> m (Code q x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Some tag -> m (q Exp)
recf (tag x -> Some tag
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some tag x
tag')) tag a
tag)
(\Some tag -> m (q Exp)
recf -> Code q r -> q Exp
forall a (m :: * -> *). Quote m => Code m a -> m Exp
unTypeCode (Code q r -> q Exp) -> m (Code q r) -> m (q Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall x. tag x -> m (Code q x)) -> m (Code q r)
forall (m :: * -> *).
Monad m =>
(forall x. tag x -> m (Code q x)) -> m (Code q r)
exprf (\tag x
tag' -> q Exp -> Code q x
forall a (m :: * -> *). Quote m => m Exp -> Code m a
unsafeCodeCoerce (q Exp -> Code q x) -> m (q Exp) -> m (Code q x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Some tag -> m (q Exp)
recf (tag x -> Some tag
forall {k} (tag :: k -> *) (a :: k). tag a -> Some tag
Some tag x
tag')))