module Unison.Codebase.Editor.SlurpComponent
  ( -- * Slurp component
    SlurpComponent (..),

    -- ** Basic constructors
    empty,
    fromTerms,
    fromTypes,
    fromCtors,

    -- ** Predicates
    isEmpty,

    -- ** Set operations
    difference,
    intersection,

    -- ** Closure
    closeWithDependencies,
  )
where

import Data.Map qualified as Map
import Data.Set qualified as Set
import Data.Tuple (swap)
import Unison.DataDeclaration qualified as DD
import Unison.Prelude hiding (empty)
import Unison.Reference (TypeReference)
import Unison.Symbol (Symbol)
import Unison.Term qualified as Term
import Unison.UnisonFile (TypecheckedUnisonFile)
import Unison.UnisonFile qualified as UF
import Unison.Util.Defns (Defns (..))

data SlurpComponent = SlurpComponent
  { SlurpComponent -> Set Symbol
types :: Set Symbol,
    SlurpComponent -> Set Symbol
terms :: Set Symbol,
    SlurpComponent -> Set Symbol
ctors :: Set Symbol
  }
  deriving (SlurpComponent -> SlurpComponent -> Bool
(SlurpComponent -> SlurpComponent -> Bool)
-> (SlurpComponent -> SlurpComponent -> Bool) -> Eq SlurpComponent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SlurpComponent -> SlurpComponent -> Bool
== :: SlurpComponent -> SlurpComponent -> Bool
$c/= :: SlurpComponent -> SlurpComponent -> Bool
/= :: SlurpComponent -> SlurpComponent -> Bool
Eq, (forall x. SlurpComponent -> Rep SlurpComponent x)
-> (forall x. Rep SlurpComponent x -> SlurpComponent)
-> Generic SlurpComponent
forall x. Rep SlurpComponent x -> SlurpComponent
forall x. SlurpComponent -> Rep SlurpComponent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SlurpComponent -> Rep SlurpComponent x
from :: forall x. SlurpComponent -> Rep SlurpComponent x
$cto :: forall x. Rep SlurpComponent x -> SlurpComponent
to :: forall x. Rep SlurpComponent x -> SlurpComponent
Generic, Eq SlurpComponent
Eq SlurpComponent =>
(SlurpComponent -> SlurpComponent -> Ordering)
-> (SlurpComponent -> SlurpComponent -> Bool)
-> (SlurpComponent -> SlurpComponent -> Bool)
-> (SlurpComponent -> SlurpComponent -> Bool)
-> (SlurpComponent -> SlurpComponent -> Bool)
-> (SlurpComponent -> SlurpComponent -> SlurpComponent)
-> (SlurpComponent -> SlurpComponent -> SlurpComponent)
-> Ord SlurpComponent
SlurpComponent -> SlurpComponent -> Bool
SlurpComponent -> SlurpComponent -> Ordering
SlurpComponent -> SlurpComponent -> SlurpComponent
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SlurpComponent -> SlurpComponent -> Ordering
compare :: SlurpComponent -> SlurpComponent -> Ordering
$c< :: SlurpComponent -> SlurpComponent -> Bool
< :: SlurpComponent -> SlurpComponent -> Bool
$c<= :: SlurpComponent -> SlurpComponent -> Bool
<= :: SlurpComponent -> SlurpComponent -> Bool
$c> :: SlurpComponent -> SlurpComponent -> Bool
> :: SlurpComponent -> SlurpComponent -> Bool
$c>= :: SlurpComponent -> SlurpComponent -> Bool
>= :: SlurpComponent -> SlurpComponent -> Bool
$cmax :: SlurpComponent -> SlurpComponent -> SlurpComponent
max :: SlurpComponent -> SlurpComponent -> SlurpComponent
$cmin :: SlurpComponent -> SlurpComponent -> SlurpComponent
min :: SlurpComponent -> SlurpComponent -> SlurpComponent
Ord, Int -> SlurpComponent -> ShowS
[SlurpComponent] -> ShowS
SlurpComponent -> String
(Int -> SlurpComponent -> ShowS)
-> (SlurpComponent -> String)
-> ([SlurpComponent] -> ShowS)
-> Show SlurpComponent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SlurpComponent -> ShowS
showsPrec :: Int -> SlurpComponent -> ShowS
$cshow :: SlurpComponent -> String
show :: SlurpComponent -> String
$cshowList :: [SlurpComponent] -> ShowS
showList :: [SlurpComponent] -> ShowS
Show)

isEmpty :: SlurpComponent -> Bool
isEmpty :: SlurpComponent -> Bool
isEmpty SlurpComponent
sc = Set Symbol -> Bool
forall a. Set a -> Bool
Set.null SlurpComponent
sc.types Bool -> Bool -> Bool
&& Set Symbol -> Bool
forall a. Set a -> Bool
Set.null SlurpComponent
sc.terms Bool -> Bool -> Bool
&& Set Symbol -> Bool
forall a. Set a -> Bool
Set.null SlurpComponent
sc.ctors

empty :: SlurpComponent
empty :: SlurpComponent
empty = SlurpComponent {$sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
forall a. Set a
Set.empty, $sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
forall a. Set a
Set.empty, $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
forall a. Set a
Set.empty}

difference :: SlurpComponent -> SlurpComponent -> SlurpComponent
difference :: SlurpComponent -> SlurpComponent -> SlurpComponent
difference SlurpComponent
c1 SlurpComponent
c2 = SlurpComponent {$sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
types', $sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
terms', $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
ctors'}
  where
    types' :: Set Symbol
types' = SlurpComponent
c1.types Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` SlurpComponent
c2.types
    terms' :: Set Symbol
terms' = SlurpComponent
c1.terms Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` SlurpComponent
c2.terms
    ctors' :: Set Symbol
ctors' = SlurpComponent
c1.ctors Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` SlurpComponent
c2.ctors

intersection :: SlurpComponent -> SlurpComponent -> SlurpComponent
intersection :: SlurpComponent -> SlurpComponent -> SlurpComponent
intersection SlurpComponent
c1 SlurpComponent
c2 = SlurpComponent {$sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
types', $sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
terms', $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
ctors'}
  where
    types' :: Set Symbol
types' = SlurpComponent
c1.types Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` SlurpComponent
c2.types
    terms' :: Set Symbol
terms' = SlurpComponent
c1.terms Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` SlurpComponent
c2.terms
    ctors' :: Set Symbol
ctors' = SlurpComponent
c1.ctors Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` SlurpComponent
c2.ctors

instance Semigroup SlurpComponent where
  SlurpComponent
c1 <> :: SlurpComponent -> SlurpComponent -> SlurpComponent
<> SlurpComponent
c2 =
    SlurpComponent
      { $sel:types:SlurpComponent :: Set Symbol
types = SlurpComponent
c1.types Set Symbol -> Set Symbol -> Set Symbol
forall a. Semigroup a => a -> a -> a
<> SlurpComponent
c2.types,
        $sel:terms:SlurpComponent :: Set Symbol
terms = SlurpComponent
c1.terms Set Symbol -> Set Symbol -> Set Symbol
forall a. Semigroup a => a -> a -> a
<> SlurpComponent
c2.terms,
        $sel:ctors:SlurpComponent :: Set Symbol
ctors = SlurpComponent
c1.ctors Set Symbol -> Set Symbol -> Set Symbol
forall a. Semigroup a => a -> a -> a
<> SlurpComponent
c2.ctors
      }

instance Monoid SlurpComponent where
  mempty :: SlurpComponent
mempty = SlurpComponent
empty

-- I'm calling this `closeWithDependencies` because it doesn't just compute
-- the dependencies of the inputs, it mixes them together.  Make sure this
-- is what you want.
closeWithDependencies ::
  forall a.
  TypecheckedUnisonFile Symbol a ->
  SlurpComponent ->
  SlurpComponent
closeWithDependencies :: forall a.
TypecheckedUnisonFile Symbol a -> SlurpComponent -> SlurpComponent
closeWithDependencies TypecheckedUnisonFile Symbol a
uf SlurpComponent
inputs = SlurpComponent
seenDefns {ctors = constructorDeps}
  where
    seenDefns :: SlurpComponent
seenDefns = (SlurpComponent -> Symbol -> SlurpComponent)
-> SlurpComponent -> Set Symbol -> SlurpComponent
forall b a. (b -> a -> b) -> b -> Set a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SlurpComponent -> Symbol -> SlurpComponent
termDeps (SlurpComponent {$sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
forall a. Monoid a => a
mempty, $sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
seenTypes, $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
forall a. Monoid a => a
mempty}) SlurpComponent
inputs.terms
    seenTypes :: Set Symbol
seenTypes = (Set Symbol -> Symbol -> Set Symbol)
-> Set Symbol -> Set Symbol -> Set Symbol
forall b a. (b -> a -> b) -> b -> Set a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Set Symbol -> Symbol -> Set Symbol
typeDeps Set Symbol
forall a. Monoid a => a
mempty SlurpComponent
inputs.types

    constructorDeps :: Set Symbol
    constructorDeps :: Set Symbol
constructorDeps = Set Symbol -> TypecheckedUnisonFile Symbol a -> Set Symbol
forall v a. Ord v => Set v -> TypecheckedUnisonFile v a -> Set v
UF.constructorsForDecls Set Symbol
seenTypes TypecheckedUnisonFile Symbol a
uf

    termDeps :: SlurpComponent -> Symbol -> SlurpComponent
    termDeps :: SlurpComponent -> Symbol -> SlurpComponent
termDeps SlurpComponent
seen Symbol
v | Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Symbol
v SlurpComponent
seen.terms = SlurpComponent
seen
    termDeps SlurpComponent
seen Symbol
v = SlurpComponent -> Maybe SlurpComponent -> SlurpComponent
forall a. a -> Maybe a -> a
fromMaybe SlurpComponent
seen do
      Term Symbol a
term <- Symbol -> Maybe (Term Symbol a)
findTerm Symbol
v
      let -- get the `v`s for the transitive dependency types
          -- (the ones for terms are just the `freeVars below`)
          -- although this isn't how you'd do it for a term that's already in codebase
          tdeps :: [Symbol]
          tdeps :: [Symbol]
tdeps = Set TypeReference -> [Symbol]
resolveTypes (Term Symbol a -> DefnsF Set TypeReference TypeReference
forall v vt at ap a.
(Ord v, Ord vt) =>
Term2 vt at ap v a -> DefnsF Set TypeReference TypeReference
Term.dependencies Term Symbol a
term).types
          seenTypes :: Set Symbol
          seenTypes :: Set Symbol
seenTypes = (Set Symbol -> Symbol -> Set Symbol)
-> Set Symbol -> [Symbol] -> Set Symbol
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Set Symbol -> Symbol -> Set Symbol
typeDeps SlurpComponent
seen.types [Symbol]
tdeps
          seenTerms :: Set Symbol
seenTerms = Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => a -> Set a -> Set a
Set.insert Symbol
v SlurpComponent
seen.terms
      SlurpComponent -> Maybe SlurpComponent
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SlurpComponent -> Maybe SlurpComponent)
-> SlurpComponent -> Maybe SlurpComponent
forall a b. (a -> b) -> a -> b
$
        (SlurpComponent -> Symbol -> SlurpComponent)
-> SlurpComponent -> Set Symbol -> SlurpComponent
forall b a. (b -> a -> b) -> b -> Set a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
          SlurpComponent -> Symbol -> SlurpComponent
termDeps
          ( SlurpComponent
seen
              SlurpComponent
-> (SlurpComponent -> SlurpComponent) -> SlurpComponent
forall a b. a -> (a -> b) -> b
& ASetter SlurpComponent SlurpComponent (Set Symbol) (Set Symbol)
#types ASetter SlurpComponent SlurpComponent (Set Symbol) (Set Symbol)
-> Set Symbol -> SlurpComponent -> SlurpComponent
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Set Symbol
seenTypes
              SlurpComponent
-> (SlurpComponent -> SlurpComponent) -> SlurpComponent
forall a b. a -> (a -> b) -> b
& ASetter SlurpComponent SlurpComponent (Set Symbol) (Set Symbol)
#terms ASetter SlurpComponent SlurpComponent (Set Symbol) (Set Symbol)
-> Set Symbol -> SlurpComponent -> SlurpComponent
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Set Symbol
seenTerms
          )
          (Term Symbol a -> Set Symbol
forall vt v a. Term' vt v a -> Set v
Term.freeVars Term Symbol a
term)

    typeDeps :: Set Symbol -> Symbol -> Set Symbol
    typeDeps :: Set Symbol -> Symbol -> Set Symbol
typeDeps Set Symbol
seen Symbol
v | Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Symbol
v Set Symbol
seen = Set Symbol
seen
    typeDeps Set Symbol
seen Symbol
v = Set Symbol -> Maybe (Set Symbol) -> Set Symbol
forall a. a -> Maybe a -> a
fromMaybe Set Symbol
seen (Maybe (Set Symbol) -> Set Symbol)
-> Maybe (Set Symbol) -> Set Symbol
forall a b. (a -> b) -> a -> b
$ do
      DataDeclaration Symbol a
dd <-
        ((TypeReference, DataDeclaration Symbol a)
 -> DataDeclaration Symbol a)
-> Maybe (TypeReference, DataDeclaration Symbol a)
-> Maybe (DataDeclaration Symbol a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TypeReference, DataDeclaration Symbol a)
-> DataDeclaration Symbol a
forall a b. (a, b) -> b
snd (Symbol
-> Map Symbol (TypeReference, DataDeclaration Symbol a)
-> Maybe (TypeReference, DataDeclaration Symbol a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Symbol
v (TypecheckedUnisonFile Symbol a
-> Map Symbol (TypeReference, DataDeclaration Symbol a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (TypeReference, DataDeclaration v a)
UF.dataDeclarations' TypecheckedUnisonFile Symbol a
uf))
          Maybe (DataDeclaration Symbol a)
-> Maybe (DataDeclaration Symbol a)
-> Maybe (DataDeclaration Symbol a)
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((TypeReference, EffectDeclaration Symbol a)
 -> DataDeclaration Symbol a)
-> Maybe (TypeReference, EffectDeclaration Symbol a)
-> Maybe (DataDeclaration Symbol a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EffectDeclaration Symbol a -> DataDeclaration Symbol a
forall v a. EffectDeclaration v a -> DataDeclaration v a
DD.toDataDecl (EffectDeclaration Symbol a -> DataDeclaration Symbol a)
-> ((TypeReference, EffectDeclaration Symbol a)
    -> EffectDeclaration Symbol a)
-> (TypeReference, EffectDeclaration Symbol a)
-> DataDeclaration Symbol a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TypeReference, EffectDeclaration Symbol a)
-> EffectDeclaration Symbol a
forall a b. (a, b) -> b
snd) (Symbol
-> Map Symbol (TypeReference, EffectDeclaration Symbol a)
-> Maybe (TypeReference, EffectDeclaration Symbol a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Symbol
v (TypecheckedUnisonFile Symbol a
-> Map Symbol (TypeReference, EffectDeclaration Symbol a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (TypeReference, EffectDeclaration v a)
UF.effectDeclarations' TypecheckedUnisonFile Symbol a
uf))
      pure $ (Set Symbol -> Symbol -> Set Symbol)
-> Set Symbol -> [Symbol] -> Set Symbol
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Set Symbol -> Symbol -> Set Symbol
typeDeps (Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => a -> Set a -> Set a
Set.insert Symbol
v Set Symbol
seen) (Set TypeReference -> [Symbol]
resolveTypes (Set TypeReference -> [Symbol]) -> Set TypeReference -> [Symbol]
forall a b. (a -> b) -> a -> b
$ DataDeclaration Symbol a -> Set TypeReference
forall v a. Ord v => DataDeclaration v a -> Set TypeReference
DD.typeDependencies DataDeclaration Symbol a
dd)

    resolveTypes :: Set TypeReference -> [Symbol]
    resolveTypes :: Set TypeReference -> [Symbol]
resolveTypes Set TypeReference
rs = [Symbol
v | TypeReference
r <- Set TypeReference -> [TypeReference]
forall a. Set a -> [a]
Set.toList Set TypeReference
rs, Just Symbol
v <- [TypeReference -> Map TypeReference Symbol -> Maybe Symbol
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup TypeReference
r Map TypeReference Symbol
typeNames]]

    findTerm :: Symbol -> Maybe (Term.Term Symbol a)
    findTerm :: Symbol -> Maybe (Term Symbol a)
findTerm Symbol
v = Symbol -> Map Symbol (Term Symbol a) -> Maybe (Term Symbol a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Symbol
v Map Symbol (Term Symbol a)
allTerms

    allTerms :: Map Symbol (Term Symbol a)
allTerms = TypecheckedUnisonFile Symbol a -> Map Symbol (Term Symbol a)
forall v a. Ord v => TypecheckedUnisonFile v a -> Map v (Term v a)
UF.allTerms TypecheckedUnisonFile Symbol a
uf

    typeNames :: Map TypeReference Symbol
    typeNames :: Map TypeReference Symbol
typeNames = Map Symbol TypeReference -> Map TypeReference Symbol
forall k v. (Ord k, Ord v) => Map k v -> Map v k
invert ((TypeReference, DataDeclaration Symbol a) -> TypeReference
forall a b. (a, b) -> a
fst ((TypeReference, DataDeclaration Symbol a) -> TypeReference)
-> Map Symbol (TypeReference, DataDeclaration Symbol a)
-> Map Symbol TypeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TypecheckedUnisonFile Symbol a
-> Map Symbol (TypeReference, DataDeclaration Symbol a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (TypeReference, DataDeclaration v a)
UF.dataDeclarations' TypecheckedUnisonFile Symbol a
uf) Map TypeReference Symbol
-> Map TypeReference Symbol -> Map TypeReference Symbol
forall a. Semigroup a => a -> a -> a
<> Map Symbol TypeReference -> Map TypeReference Symbol
forall k v. (Ord k, Ord v) => Map k v -> Map v k
invert ((TypeReference, EffectDeclaration Symbol a) -> TypeReference
forall a b. (a, b) -> a
fst ((TypeReference, EffectDeclaration Symbol a) -> TypeReference)
-> Map Symbol (TypeReference, EffectDeclaration Symbol a)
-> Map Symbol TypeReference
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TypecheckedUnisonFile Symbol a
-> Map Symbol (TypeReference, EffectDeclaration Symbol a)
forall v a.
TypecheckedUnisonFile v a
-> Map v (TypeReference, EffectDeclaration v a)
UF.effectDeclarations' TypecheckedUnisonFile Symbol a
uf)

    invert :: forall k v. (Ord k) => (Ord v) => Map k v -> Map v k
    invert :: forall k v. (Ord k, Ord v) => Map k v -> Map v k
invert Map k v
m = [(v, k)] -> Map v k
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((k, v) -> (v, k)
forall a b. (a, b) -> (b, a)
swap ((k, v) -> (v, k)) -> [(k, v)] -> [(v, k)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map k v -> [(k, v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map k v
m)

fromTypes :: Set Symbol -> SlurpComponent
fromTypes :: Set Symbol -> SlurpComponent
fromTypes Set Symbol
vs = SlurpComponent {$sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
forall a. Set a
Set.empty, $sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
vs, $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
forall a. Set a
Set.empty}

fromTerms :: Set Symbol -> SlurpComponent
fromTerms :: Set Symbol -> SlurpComponent
fromTerms Set Symbol
vs = SlurpComponent {$sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
vs, $sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
forall a. Set a
Set.empty, $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
forall a. Set a
Set.empty}

fromCtors :: Set Symbol -> SlurpComponent
fromCtors :: Set Symbol -> SlurpComponent
fromCtors Set Symbol
vs = SlurpComponent {$sel:terms:SlurpComponent :: Set Symbol
terms = Set Symbol
forall a. Set a
Set.empty, $sel:types:SlurpComponent :: Set Symbol
types = Set Symbol
forall a. Set a
Set.empty, $sel:ctors:SlurpComponent :: Set Symbol
ctors = Set Symbol
vs}