{-# OPTIONS_GHC -fno-warn-orphans #-}

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}

module UntypedPlutusCore.Core.Instance.Scoping () where

import PlutusPrelude

import UntypedPlutusCore.Core.Type

import PlutusCore.Check.Scoping
import PlutusCore.Name.Unique
import PlutusCore.Quote

import Data.Proxy
import Data.Vector qualified as Vector

firstBound :: Term name uni fun ann -> [name]
firstBound :: forall name (uni :: * -> *) fun ann.
Term name uni fun ann -> [name]
firstBound (Apply ann
_ (LamAbs ann
_ name
name Term name uni fun ann
body) Term name uni fun ann
_) = name
name name -> [name] -> [name]
forall a. a -> [a] -> [a]
: Term name uni fun ann -> [name]
forall name (uni :: * -> *) fun ann.
Term name uni fun ann -> [name]
firstBound Term name uni fun ann
body
firstBound Term name uni fun ann
_                                = []

instance name ~ Name => Reference Name (Term name uni fun) where
    referenceVia :: (forall name. ToScopedName name => name -> NameAnn)
-> Name -> Term name uni fun NameAnn -> Term name uni fun NameAnn
referenceVia forall name. ToScopedName name => name -> NameAnn
reg Name
name Term name uni fun NameAnn
term = NameAnn
-> Term name uni fun NameAnn
-> Term name uni fun NameAnn
-> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply NameAnn
NotAName Term name uni fun NameAnn
term (Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Term name uni fun NameAnn -> Term name uni fun NameAnn
forall a b. (a -> b) -> a -> b
$ NameAnn -> name -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann
Var (Name -> NameAnn
forall name. ToScopedName name => name -> NameAnn
reg Name
name) name
Name
name

instance name ~ Name => EstablishScoping (Term name uni fun) where
    establishScoping :: forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
establishScoping (LamAbs ann
_ name
nameDup Term name uni fun ann
body)  = do
        Name
name <- Name -> QuoteT Identity Name
forall (m :: * -> *). MonadQuote m => Name -> m Name
freshenName name
Name
nameDup
        (NameAnn
 -> name
 -> Proxy NameAnn
 -> Term name uni fun NameAnn
 -> Term name uni fun NameAnn)
-> name
-> Proxy ann
-> Term name uni fun ann
-> Quote (Term name uni fun NameAnn)
forall name (value :: * -> *) (sort :: * -> *) ann.
(Reference name value, ToScopedName name, EstablishScoping sort,
 EstablishScoping value) =>
(NameAnn -> name -> sort NameAnn -> value NameAnn -> value NameAnn)
-> name -> sort ann -> value ann -> Quote (value NameAnn)
establishScopingBinder (\NameAnn
ann name
name' Proxy NameAnn
_ -> NameAnn
-> name -> Term name uni fun NameAnn -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann -> Term name uni fun ann
LamAbs NameAnn
ann name
name') name
Name
name Proxy ann
forall {k} (t :: k). Proxy t
Proxy Term name uni fun ann
body
    establishScoping (Delay ann
_ Term name uni fun ann
body) = NameAnn -> Term name uni fun NameAnn -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Delay NameAnn
NotAName (Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
body
    establishScoping (Apply ann
_ Term name uni fun ann
fun Term name uni fun ann
arg) =
        NameAnn
-> Term name uni fun NameAnn
-> Term name uni fun NameAnn
-> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply NameAnn
NotAName (Term name uni fun NameAnn
 -> Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
-> QuoteT
     Identity (Term name uni fun NameAnn -> Term name uni fun NameAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
fun QuoteT
  Identity (Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
forall a b.
QuoteT Identity (a -> b) -> QuoteT Identity a -> QuoteT Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
arg
    establishScoping (Error ann
_) = Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a b. (a -> b) -> a -> b
$ NameAnn -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann. ann -> Term name uni fun ann
Error NameAnn
NotAName
    establishScoping (Force ann
_ Term name uni fun ann
term) = NameAnn -> Term name uni fun NameAnn -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Force NameAnn
NotAName (Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
-> Quote (Term name uni fun NameAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
term
    establishScoping (Var ann
_ name
nameDup) = do
        Name
name <- Name -> QuoteT Identity Name
forall (m :: * -> *). MonadQuote m => Name -> m Name
freshenName name
Name
nameDup
        Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a b. (a -> b) -> a -> b
$ NameAnn -> name -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann
Var (Name -> NameAnn
forall name. ToScopedName name => name -> NameAnn
registerFree Name
name) name
Name
name
    establishScoping (Constant ann
_ Some (ValueOf uni)
con) = Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a b. (a -> b) -> a -> b
$ NameAnn -> Some (ValueOf uni) -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> Some (ValueOf uni) -> Term name uni fun ann
Constant NameAnn
NotAName Some (ValueOf uni)
con
    establishScoping (Builtin ann
_ fun
bi) = Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a b. (a -> b) -> a -> b
$ NameAnn -> fun -> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin NameAnn
NotAName fun
bi
    establishScoping (Constr ann
_ Word64
i [Term name uni fun ann]
es) = NameAnn
-> Word64
-> [Term name uni fun NameAnn]
-> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> Word64 -> [Term name uni fun ann] -> Term name uni fun ann
Constr NameAnn
NotAName (Word64
 -> [Term name uni fun NameAnn] -> Term name uni fun NameAnn)
-> QuoteT Identity Word64
-> QuoteT
     Identity ([Term name uni fun NameAnn] -> Term name uni fun NameAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word64 -> QuoteT Identity Word64
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
i QuoteT
  Identity ([Term name uni fun NameAnn] -> Term name uni fun NameAnn)
-> QuoteT Identity [Term name uni fun NameAnn]
-> Quote (Term name uni fun NameAnn)
forall a b.
QuoteT Identity (a -> b) -> QuoteT Identity a -> QuoteT Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Term name uni fun ann -> Quote (Term name uni fun NameAnn))
-> [Term name uni fun ann]
-> QuoteT Identity [Term name uni fun NameAnn]
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) -> [a] -> f [b]
traverse Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping [Term name uni fun ann]
es
    establishScoping (Case ann
_ Term name uni fun ann
a Vector (Term name uni fun ann)
es) = do
        Vector (Term name uni fun NameAnn)
esScoped <- (Term name uni fun ann -> Quote (Term name uni fun NameAnn))
-> Vector (Term name uni fun ann)
-> QuoteT Identity (Vector (Term name uni fun NameAnn))
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) -> Vector a -> f (Vector b)
traverse Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Vector (Term name uni fun ann)
es
        let esScopedPoked :: [((Term name uni fun NameAnn, [name]),
  [(Term name uni fun NameAnn, [name])])]
esScopedPoked = [(Term name uni fun NameAnn, [name])]
-> [((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])]
forall a. [a] -> [(a, [a])]
addTheRest ([(Term name uni fun NameAnn, [name])]
 -> [((Term name uni fun NameAnn, [name]),
      [(Term name uni fun NameAnn, [name])])])
-> ([Term name uni fun NameAnn]
    -> [(Term name uni fun NameAnn, [name])])
-> [Term name uni fun NameAnn]
-> [((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Term name uni fun NameAnn -> (Term name uni fun NameAnn, [name]))
-> [Term name uni fun NameAnn]
-> [(Term name uni fun NameAnn, [name])]
forall a b. (a -> b) -> [a] -> [b]
map (\Term name uni fun NameAnn
e -> (Term name uni fun NameAnn
e, Term name uni fun NameAnn -> [name]
forall name (uni :: * -> *) fun ann.
Term name uni fun ann -> [name]
firstBound Term name uni fun NameAnn
e)) ([Term name uni fun NameAnn]
 -> [((Term name uni fun NameAnn, [name]),
      [(Term name uni fun NameAnn, [name])])])
-> [Term name uni fun NameAnn]
-> [((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])]
forall a b. (a -> b) -> a -> b
$ Vector (Term name uni fun NameAnn) -> [Term name uni fun NameAnn]
forall a. Vector a -> [a]
Vector.toList Vector (Term name uni fun NameAnn)
esScoped
            branchBounds :: [[name]]
branchBounds = (((Term name uni fun NameAnn, [name]),
  [(Term name uni fun NameAnn, [name])])
 -> [name])
-> [((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])]
-> [[name]]
forall a b. (a -> b) -> [a] -> [b]
map ((Term name uni fun NameAnn, [name]) -> [name]
forall a b. (a, b) -> b
snd ((Term name uni fun NameAnn, [name]) -> [name])
-> (((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])
    -> (Term name uni fun NameAnn, [name]))
-> ((Term name uni fun NameAnn, [name]),
    [(Term name uni fun NameAnn, [name])])
-> [name]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Term name uni fun NameAnn, [name]),
 [(Term name uni fun NameAnn, [name])])
-> (Term name uni fun NameAnn, [name])
forall a b. (a, b) -> a
fst) [((Term name uni fun NameAnn, [name]),
  [(Term name uni fun NameAnn, [name])])]
esScopedPoked
            referenceInBranch :: ((t NameAnn, b), [(a, b)]) -> t NameAnn
referenceInBranch ((t NameAnn
branch, b
_), [(a, b)]
others) = [b] -> t NameAnn -> t NameAnn
forall n (t :: * -> *).
Reference n t =>
n -> t NameAnn -> t NameAnn
referenceOutOfScope (((a, b) -> b) -> [(a, b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> b
forall a b. (a, b) -> b
snd [(a, b)]
others) t NameAnn
branch
        Term name uni fun NameAnn
aScoped <- Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann -> Quote (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
a
        -- For each of the branches reference (as out-of-scope) the variables bound in that branch
        -- in all the other ones, as well as outside of the whole case-expression. This is to check
        -- that none of the transformations leak variables outside of the branch they're bound in.
        Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> (Term name uni fun NameAnn -> Term name uni fun NameAnn)
-> Term name uni fun NameAnn
-> Quote (Term name uni fun NameAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[name]] -> Term name uni fun NameAnn -> Term name uni fun NameAnn
forall n (t :: * -> *).
Reference n t =>
n -> t NameAnn -> t NameAnn
referenceOutOfScope [[name]]
branchBounds (Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn))
-> Term name uni fun NameAnn -> Quote (Term name uni fun NameAnn)
forall a b. (a -> b) -> a -> b
$
            NameAnn
-> Term name uni fun NameAnn
-> Vector (Term name uni fun NameAnn)
-> Term name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Vector (Term name uni fun ann)
-> Term name uni fun ann
Case NameAnn
NotAName Term name uni fun NameAnn
aScoped (Vector (Term name uni fun NameAnn) -> Term name uni fun NameAnn)
-> ([Term name uni fun NameAnn]
    -> Vector (Term name uni fun NameAnn))
-> [Term name uni fun NameAnn]
-> Term name uni fun NameAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Term name uni fun NameAnn] -> Vector (Term name uni fun NameAnn)
forall a. [a] -> Vector a
Vector.fromList ([Term name uni fun NameAnn] -> Term name uni fun NameAnn)
-> [Term name uni fun NameAnn] -> Term name uni fun NameAnn
forall a b. (a -> b) -> a -> b
$ (((Term name uni fun NameAnn, [name]),
  [(Term name uni fun NameAnn, [name])])
 -> Term name uni fun NameAnn)
-> [((Term name uni fun NameAnn, [name]),
     [(Term name uni fun NameAnn, [name])])]
-> [Term name uni fun NameAnn]
forall a b. (a -> b) -> [a] -> [b]
map ((Term name uni fun NameAnn, [name]),
 [(Term name uni fun NameAnn, [name])])
-> Term name uni fun NameAnn
forall {b} {t :: * -> *} {b} {a}.
Reference b t =>
((t NameAnn, b), [(a, b)]) -> t NameAnn
referenceInBranch [((Term name uni fun NameAnn, [name]),
  [(Term name uni fun NameAnn, [name])])]
esScopedPoked

instance name ~ Name => EstablishScoping (Program name uni fun) where
    establishScoping :: forall ann.
Program name uni fun ann -> Quote (Program name uni fun NameAnn)
establishScoping (Program ann
_ Version
ver Term name uni fun ann
term) = NameAnn
-> Version
-> Term name uni fun NameAnn
-> Program name uni fun NameAnn
forall name (uni :: * -> *) fun ann.
ann -> Version -> Term name uni fun ann -> Program name uni fun ann
Program NameAnn
NotAName Version
ver (Term name uni fun NameAnn -> Program name uni fun NameAnn)
-> QuoteT Identity (Term name uni fun NameAnn)
-> Quote (Program name uni fun NameAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun ann
-> QuoteT Identity (Term name uni fun NameAnn)
forall ann.
Term name uni fun ann
-> QuoteT Identity (Term name uni fun NameAnn)
forall (t :: * -> *) ann.
EstablishScoping t =>
t ann -> Quote (t NameAnn)
establishScoping Term name uni fun ann
term

instance name ~ Name => CollectScopeInfo (Term name uni fun) where
    collectScopeInfo :: Term name uni fun NameAnn -> ScopeErrorOrInfo
collectScopeInfo (LamAbs NameAnn
ann name
name Term name uni fun NameAnn
body) = NameAnn -> name -> ScopeErrorOrInfo
forall name.
ToScopedName name =>
NameAnn -> name -> ScopeErrorOrInfo
handleSname NameAnn
ann name
name ScopeErrorOrInfo -> ScopeErrorOrInfo -> ScopeErrorOrInfo
forall a. Semigroup a => a -> a -> a
<> Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
body
    collectScopeInfo (Delay NameAnn
_ Term name uni fun NameAnn
body)         = Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
body
    collectScopeInfo (Apply NameAnn
_ Term name uni fun NameAnn
fun Term name uni fun NameAnn
arg)      = Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
fun ScopeErrorOrInfo -> ScopeErrorOrInfo -> ScopeErrorOrInfo
forall a. Semigroup a => a -> a -> a
<> Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
arg
    collectScopeInfo (Error NameAnn
_)              = ScopeErrorOrInfo
forall a. Monoid a => a
mempty
    collectScopeInfo (Force NameAnn
_ Term name uni fun NameAnn
term)         = Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
term
    collectScopeInfo (Var NameAnn
ann name
name)         = NameAnn -> name -> ScopeErrorOrInfo
forall name.
ToScopedName name =>
NameAnn -> name -> ScopeErrorOrInfo
handleSname NameAnn
ann name
name
    collectScopeInfo (Constant NameAnn
_ Some (ValueOf uni)
_)         = ScopeErrorOrInfo
forall a. Monoid a => a
mempty
    collectScopeInfo (Builtin NameAnn
_ fun
_)          = ScopeErrorOrInfo
forall a. Monoid a => a
mempty
    collectScopeInfo (Constr NameAnn
_ Word64
_ [Term name uni fun NameAnn]
es)        = (Term name uni fun NameAnn -> ScopeErrorOrInfo)
-> [Term name uni fun NameAnn] -> ScopeErrorOrInfo
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo [Term name uni fun NameAnn]
es
    collectScopeInfo (Case NameAnn
_ Term name uni fun NameAnn
arg Vector (Term name uni fun NameAnn)
cs)        = Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
arg ScopeErrorOrInfo -> ScopeErrorOrInfo -> ScopeErrorOrInfo
forall a. Semigroup a => a -> a -> a
<> (Term name uni fun NameAnn -> ScopeErrorOrInfo)
-> Vector (Term name uni fun NameAnn) -> ScopeErrorOrInfo
forall m a. Monoid m => (a -> m) -> Vector a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Vector (Term name uni fun NameAnn)
cs

instance name ~ Name => CollectScopeInfo (Program name uni fun) where
    collectScopeInfo :: Program name uni fun NameAnn -> ScopeErrorOrInfo
collectScopeInfo (Program NameAnn
_ Version
_ Term name uni fun NameAnn
term) = Term name uni fun NameAnn -> ScopeErrorOrInfo
forall (t :: * -> *).
CollectScopeInfo t =>
t NameAnn -> ScopeErrorOrInfo
collectScopeInfo Term name uni fun NameAnn
term