{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Monad.Free.Foil.Annotated (
AnnSig(..),
AnnAST,
AnnScopedAST,
pattern AnnNode,
annotationOf,
freeVarsOfAnnotated,
) where
import Data.Bifoldable
import Data.Bifunctor
import Data.Bitraversable
import Data.Kind (Type)
import Data.Maybe (mapMaybe)
import Data.ZipMatchK.TH (deriveZipMatchK2)
import Generics.Kind (GenericK (..), Field, Var0, Var1, (:$:),
Atom ((:@:)), (:*:))
import qualified GHC.Generics as GHC
import qualified Control.Monad.Foil as Foil
import Control.Monad.Free.Foil
data AnnSig (ann :: Type -> Type) (sig :: Type -> Type -> Type) scope term
= AnnSig (ann term) (sig scope term)
deriving ((forall x.
AnnSig ann sig scope term -> Rep (AnnSig ann sig scope term) x)
-> (forall x.
Rep (AnnSig ann sig scope term) x -> AnnSig ann sig scope term)
-> Generic (AnnSig ann sig scope term)
forall x.
Rep (AnnSig ann sig scope term) x -> AnnSig ann sig scope term
forall x.
AnnSig ann sig scope term -> Rep (AnnSig ann sig scope term) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (ann :: * -> *) (sig :: * -> * -> *) scope term x.
Rep (AnnSig ann sig scope term) x -> AnnSig ann sig scope term
forall (ann :: * -> *) (sig :: * -> * -> *) scope term x.
AnnSig ann sig scope term -> Rep (AnnSig ann sig scope term) x
$cfrom :: forall (ann :: * -> *) (sig :: * -> * -> *) scope term x.
AnnSig ann sig scope term -> Rep (AnnSig ann sig scope term) x
from :: forall x.
AnnSig ann sig scope term -> Rep (AnnSig ann sig scope term) x
$cto :: forall (ann :: * -> *) (sig :: * -> * -> *) scope term x.
Rep (AnnSig ann sig scope term) x -> AnnSig ann sig scope term
to :: forall x.
Rep (AnnSig ann sig scope term) x -> AnnSig ann sig scope term
GHC.Generic)
deriving instance (Functor ann, Functor (sig scope))
=> Functor (AnnSig ann sig scope)
deriving instance (Foldable ann, Foldable (sig scope))
=> Foldable (AnnSig ann sig scope)
deriving instance (Traversable ann, Traversable (sig scope))
=> Traversable (AnnSig ann sig scope)
instance (Functor ann, Bifunctor sig) => Bifunctor (AnnSig ann sig) where
bimap :: forall a b c d.
(a -> b) -> (c -> d) -> AnnSig ann sig a c -> AnnSig ann sig b d
bimap a -> b
f c -> d
g (AnnSig ann c
ann sig a c
sig) = ann d -> sig b d -> AnnSig ann sig b d
forall (ann :: * -> *) (sig :: * -> * -> *) scope term.
ann term -> sig scope term -> AnnSig ann sig scope term
AnnSig ((c -> d) -> ann c -> ann d
forall a b. (a -> b) -> ann a -> ann b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> d
g ann c
ann) ((a -> b) -> (c -> d) -> sig a c -> sig b d
forall a b c d. (a -> b) -> (c -> d) -> sig a c -> sig b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f c -> d
g sig a c
sig)
instance Bifoldable sig => Bifoldable (AnnSig ann sig) where
bifoldMap :: forall m a b.
Monoid m =>
(a -> m) -> (b -> m) -> AnnSig ann sig a b -> m
bifoldMap a -> m
f b -> m
g (AnnSig ann b
_ann sig a b
sig) = (a -> m) -> (b -> m) -> sig a b -> m
forall m a b. Monoid m => (a -> m) -> (b -> m) -> sig a b -> m
forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap a -> m
f b -> m
g sig a b
sig
instance (Traversable ann, Bitraversable sig) => Bitraversable (AnnSig ann sig) where
bitraverse :: forall (f :: * -> *) a c b d.
Applicative f =>
(a -> f c)
-> (b -> f d) -> AnnSig ann sig a b -> f (AnnSig ann sig c d)
bitraverse a -> f c
f b -> f d
g (AnnSig ann b
ann sig a b
sig) = ann d -> sig c d -> AnnSig ann sig c d
forall (ann :: * -> *) (sig :: * -> * -> *) scope term.
ann term -> sig scope term -> AnnSig ann sig scope term
AnnSig (ann d -> sig c d -> AnnSig ann sig c d)
-> f (ann d) -> f (sig c d -> AnnSig ann sig c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (b -> f d) -> ann b -> f (ann d)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> ann a -> f (ann b)
traverse b -> f d
g ann b
ann f (sig c d -> AnnSig ann sig c d)
-> f (sig c d) -> f (AnnSig ann sig c d)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> f c) -> (b -> f d) -> sig a b -> f (sig c d)
forall (f :: * -> *) a c b d.
Applicative f =>
(a -> f c) -> (b -> f d) -> sig a b -> f (sig c d)
forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse a -> f c
f b -> f d
g sig a b
sig
instance GenericK (AnnSig ann sig) where
type RepK (AnnSig ann sig) =
Field (ann :$: Var1) :*: Field ((sig :$: Var0) :@: Var1)
deriveZipMatchK2 ''AnnSig
type AnnAST binder ann sig = AST binder (AnnSig ann sig)
type AnnScopedAST binder ann sig = ScopedAST binder (AnnSig ann sig)
pattern AnnNode
:: ann (AnnAST binder ann sig n)
-> sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
-> AnnAST binder ann sig n
pattern $mAnnNode :: forall {r} {ann :: * -> *} {binder :: S -> S -> *}
{sig :: * -> * -> *} {n :: S}.
AnnAST binder ann sig n
-> (ann (AnnAST binder ann sig n)
-> sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
-> r)
-> ((# #) -> r)
-> r
$bAnnNode :: forall (ann :: * -> *) (binder :: S -> S -> *) (sig :: * -> * -> *)
(n :: S).
ann (AnnAST binder ann sig n)
-> sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
-> AnnAST binder ann sig n
AnnNode ann sig = Node (AnnSig ann sig)
{-# COMPLETE Var, AnnNode #-}
annotationOf :: AnnAST binder ann sig n -> Maybe (ann (AnnAST binder ann sig n))
annotationOf :: forall (binder :: S -> S -> *) (ann :: * -> *) (sig :: * -> * -> *)
(n :: S).
AnnAST binder ann sig n -> Maybe (ann (AnnAST binder ann sig n))
annotationOf = \case
Var Name n
_ -> Maybe (ann (AnnAST binder ann sig n))
forall a. Maybe a
Nothing
AnnNode ann (AnnAST binder ann sig n)
ann sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
_ -> ann (AnnAST binder ann sig n)
-> Maybe (ann (AnnAST binder ann sig n))
forall a. a -> Maybe a
Just ann (AnnAST binder ann sig n)
ann
freeVarsOfAnnotated
:: (Foil.Distinct n, Foil.CoSinkable binder, Bifoldable sig, Foldable ann)
=> AnnAST binder ann sig n -> [Foil.Name n]
freeVarsOfAnnotated :: forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnAST binder ann sig n -> [Name n]
freeVarsOfAnnotated = \case
Var Name n
name -> [Name n
name]
AnnNode ann (AnnAST binder ann sig n)
ann sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
sig ->
(AnnAST binder ann sig n -> [Name n])
-> ann (AnnAST binder ann sig n) -> [Name n]
forall m a. Monoid m => (a -> m) -> ann a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap AnnAST binder ann sig n -> [Name n]
forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnAST binder ann sig n -> [Name n]
freeVarsOfAnnotated ann (AnnAST binder ann sig n)
ann
[Name n] -> [Name n] -> [Name n]
forall a. Semigroup a => a -> a -> a
<> (AnnScopedAST binder ann sig n -> [Name n])
-> (AnnAST binder ann sig n -> [Name n])
-> sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
-> [Name n]
forall m a b. Monoid m => (a -> m) -> (b -> m) -> sig a b -> m
forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap AnnScopedAST binder ann sig n -> [Name n]
forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnScopedAST binder ann sig n -> [Name n]
freeVarsOfAnnotatedScoped AnnAST binder ann sig n -> [Name n]
forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnAST binder ann sig n -> [Name n]
freeVarsOfAnnotated sig (AnnScopedAST binder ann sig n) (AnnAST binder ann sig n)
sig
freeVarsOfAnnotatedScoped
:: (Foil.Distinct n, Foil.CoSinkable binder, Bifoldable sig, Foldable ann)
=> AnnScopedAST binder ann sig n -> [Foil.Name n]
freeVarsOfAnnotatedScoped :: forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnScopedAST binder ann sig n -> [Name n]
freeVarsOfAnnotatedScoped (ScopedAST binder n l
binder AST binder (AnnSig ann sig) l
body) =
case binder n l -> DistinctEvidence l
forall (n :: S) (pattern :: S -> S -> *) (l :: S).
(Distinct n, CoSinkable pattern) =>
pattern n l -> DistinctEvidence l
Foil.assertDistinct binder n l
binder of
DistinctEvidence l
Foil.Distinct ->
(Name l -> Maybe (Name n)) -> [Name l] -> [Name n]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (binder n l -> Name l -> Maybe (Name n)
forall (pattern :: S -> S -> *) (n :: S) (l :: S).
(Distinct n, CoSinkable pattern) =>
pattern n l -> Name l -> Maybe (Name n)
Foil.unsinkNamePattern binder n l
binder) (AST binder (AnnSig ann sig) l -> [Name l]
forall (n :: S) (binder :: S -> S -> *) (sig :: * -> * -> *)
(ann :: * -> *).
(Distinct n, CoSinkable binder, Bifoldable sig, Foldable ann) =>
AnnAST binder ann sig n -> [Name n]
freeVarsOfAnnotated AST binder (AnnSig ann sig) l
body)