module FP.Prelude.TemplateHaskell where import FP.Prelude.Core import Language.Haskell.TH import Language.Haskell.TH.Syntax import FP.Prelude.Lens import FP.Prelude.Effects import FP.Prelude.Monads () import FP.Prelude.DSL import FP.Prelude.Lib import qualified Prelude class MonadQ (m ∷ ★ → ★) where qio ∷ Q a → m a instance Functor Q where map = mmap instance Monad Q where {return = Prelude.return;(≫=) = (Prelude.>>=)} instance MonadIO Q where io = runIO instance MonadQ Q where qio = id instance Apply Exp where (◇⋅) = AppE instance Tup Exp where tup = TupE instance Tup Pat where tup = TupP instance Apply Type where (◇⋅) = AppT instance Tup Type where tup ts = TupleT (𝕚 $ length ts) ◇⋅| ts instance Arrow Type where f ◇⇨ x = ArrowT ◇⋅ f ◇⋅ x thString ∷ 𝕊 → Exp thString = LitE ∘ StringL ∘ chars thConName ∷ Con → Name thConName (NormalC n _) = n thConName (RecC n _) = n thConName (InfixC _ n _) = n thConName (ForallC _ _ c) = thConName c thTyVarBndrName ∷ TyVarBndr → Name thTyVarBndrName (PlainTV name) = name thTyVarBndrName (KindedTV name _) = name thSingleClause ∷ [Pat] → Exp → Clause thSingleClause p b = Clause p (NormalB b) [] thSingleMatch ∷ Pat → Exp → Match thSingleMatch p b = Match p (NormalB b) [] thViewSimpleCon ∷ Con → Maybe (Name,[Type]) thViewSimpleCon (NormalC name strictTypes) = Just (name,map snd strictTypes) thViewSimpleCon (RecC name varStrictTypes) = Just (name,map ff varStrictTypes) where ff (_,_,x) = x thViewSimpleCon (InfixC (_,typeL) name (_,typeR)) = Just (name,[typeL,typeR]) thViewSimpleCon (ForallC _ _ _) = Nothing thTyConIL ∷ Prism Info Dec thTyConIL = Prism { view = \case TyConI d → Just d _ → Nothing , construct = TyConI } thDataDL ∷ Prism Dec (Cxt,Name,[TyVarBndr],[Con],[Name]) thDataDL = Prism { view = \case DataD cx t args cs ders → Just (cx,t,args,cs,ders) _ → Nothing , construct = \ (cx,t,args,cs,ders) → DataD cx t args cs ders } thNewtypeDL ∷ Prism Dec (Cxt,Name,[TyVarBndr],Con,[Name]) thNewtypeDL = Prism { view = \case NewtypeD cx t args c ders → Just (cx,t,args,c,ders) _ → Nothing , construct = \ (cx,t,args,c,ders) → NewtypeD cx t args c ders } thViewADT ∷ Dec → Maybe (Cxt,Name,[TyVarBndr],[Con],[Name]) thViewADT d = view thDataDL d <|> (ff ^∘ view thNewtypeDL) d where ff (cx,t,args,c,ders) = (cx,t,args,[c],ders) thViewSingleConADT ∷ Dec → Maybe (Cxt,Name,[TyVarBndr],Con,[Name]) thViewSingleConADT dec = do (cx,t,args,cs,ders) ← thViewADT dec c ← view singleL cs return(cx,t,args,c,ders) thRecCL ∷ Prism Con (Name,[VarStrictType]) thRecCL = Prism { view = \case RecC n fs → Just (n,fs) _ → Nothing , construct = \ (n,fs) → RecC n fs }