module Unison.Typechecker.Variance where
import Control.Monad.State.Strict
import Data.Foldable (foldl', traverse_)
import Data.Graph (flattenSCC, stronglyConnComp)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Unison.DataDeclaration
import Unison.Reference
import Unison.Type
import Unison.Typechecker.TypeLookup (TypeLookup (..))
import Unison.Var (Var, freshIn)
data Polarity v = Positive | Negative | Exact | As v | Op v
deriving (Polarity v -> Polarity v -> Bool
(Polarity v -> Polarity v -> Bool)
-> (Polarity v -> Polarity v -> Bool) -> Eq (Polarity v)
forall v. Eq v => Polarity v -> Polarity v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall v. Eq v => Polarity v -> Polarity v -> Bool
== :: Polarity v -> Polarity v -> Bool
$c/= :: forall v. Eq v => Polarity v -> Polarity v -> Bool
/= :: Polarity v -> Polarity v -> Bool
Eq, Eq (Polarity v)
Eq (Polarity v) =>
(Polarity v -> Polarity v -> Ordering)
-> (Polarity v -> Polarity v -> Bool)
-> (Polarity v -> Polarity v -> Bool)
-> (Polarity v -> Polarity v -> Bool)
-> (Polarity v -> Polarity v -> Bool)
-> (Polarity v -> Polarity v -> Polarity v)
-> (Polarity v -> Polarity v -> Polarity v)
-> Ord (Polarity v)
Polarity v -> Polarity v -> Bool
Polarity v -> Polarity v -> Ordering
Polarity v -> Polarity v -> Polarity v
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
forall v. Ord v => Eq (Polarity v)
forall v. Ord v => Polarity v -> Polarity v -> Bool
forall v. Ord v => Polarity v -> Polarity v -> Ordering
forall v. Ord v => Polarity v -> Polarity v -> Polarity v
$ccompare :: forall v. Ord v => Polarity v -> Polarity v -> Ordering
compare :: Polarity v -> Polarity v -> Ordering
$c< :: forall v. Ord v => Polarity v -> Polarity v -> Bool
< :: Polarity v -> Polarity v -> Bool
$c<= :: forall v. Ord v => Polarity v -> Polarity v -> Bool
<= :: Polarity v -> Polarity v -> Bool
$c> :: forall v. Ord v => Polarity v -> Polarity v -> Bool
> :: Polarity v -> Polarity v -> Bool
$c>= :: forall v. Ord v => Polarity v -> Polarity v -> Bool
>= :: Polarity v -> Polarity v -> Bool
$cmax :: forall v. Ord v => Polarity v -> Polarity v -> Polarity v
max :: Polarity v -> Polarity v -> Polarity v
$cmin :: forall v. Ord v => Polarity v -> Polarity v -> Polarity v
min :: Polarity v -> Polarity v -> Polarity v
Ord, Int -> Polarity v -> ShowS
[Polarity v] -> ShowS
Polarity v -> String
(Int -> Polarity v -> ShowS)
-> (Polarity v -> String)
-> ([Polarity v] -> ShowS)
-> Show (Polarity v)
forall v. Show v => Int -> Polarity v -> ShowS
forall v. Show v => [Polarity v] -> ShowS
forall v. Show v => Polarity v -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall v. Show v => Int -> Polarity v -> ShowS
showsPrec :: Int -> Polarity v -> ShowS
$cshow :: forall v. Show v => Polarity v -> String
show :: Polarity v -> String
$cshowList :: forall v. Show v => [Polarity v] -> ShowS
showList :: [Polarity v] -> ShowS
Show)
inv :: Polarity v -> Polarity v
inv :: forall v. Polarity v -> Polarity v
inv Polarity v
Positive = Polarity v
forall v. Polarity v
Negative
inv Polarity v
Negative = Polarity v
forall v. Polarity v
Positive
inv (As v
v) = v -> Polarity v
forall v. v -> Polarity v
Op v
v
inv (Op v
v) = v -> Polarity v
forall v. v -> Polarity v
As v
v
inv Polarity v
Exact = Polarity v
forall v. Polarity v
Exact
act :: Polarity v -> Polarity v -> Polarity v
act :: forall v. Polarity v -> Polarity v -> Polarity v
act Polarity v
Positive Polarity v
p = Polarity v
p
act Polarity v
Negative Polarity v
p = Polarity v -> Polarity v
forall v. Polarity v -> Polarity v
inv Polarity v
p
act Polarity v
Exact Polarity v
_ = Polarity v
forall v. Polarity v
Exact
act Polarity v
_ Polarity v
_ = Polarity v
forall v. Polarity v
Exact
data Variance = Any | Pos | Neg | Inv
deriving (Variance -> Variance -> Bool
(Variance -> Variance -> Bool)
-> (Variance -> Variance -> Bool) -> Eq Variance
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Variance -> Variance -> Bool
== :: Variance -> Variance -> Bool
$c/= :: Variance -> Variance -> Bool
/= :: Variance -> Variance -> Bool
Eq, Eq Variance
Eq Variance =>
(Variance -> Variance -> Ordering)
-> (Variance -> Variance -> Bool)
-> (Variance -> Variance -> Bool)
-> (Variance -> Variance -> Bool)
-> (Variance -> Variance -> Bool)
-> (Variance -> Variance -> Variance)
-> (Variance -> Variance -> Variance)
-> Ord Variance
Variance -> Variance -> Bool
Variance -> Variance -> Ordering
Variance -> Variance -> Variance
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 :: Variance -> Variance -> Ordering
compare :: Variance -> Variance -> Ordering
$c< :: Variance -> Variance -> Bool
< :: Variance -> Variance -> Bool
$c<= :: Variance -> Variance -> Bool
<= :: Variance -> Variance -> Bool
$c> :: Variance -> Variance -> Bool
> :: Variance -> Variance -> Bool
$c>= :: Variance -> Variance -> Bool
>= :: Variance -> Variance -> Bool
$cmax :: Variance -> Variance -> Variance
max :: Variance -> Variance -> Variance
$cmin :: Variance -> Variance -> Variance
min :: Variance -> Variance -> Variance
Ord, Int -> Variance -> ShowS
[Variance] -> ShowS
Variance -> String
(Int -> Variance -> ShowS)
-> (Variance -> String) -> ([Variance] -> ShowS) -> Show Variance
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Variance -> ShowS
showsPrec :: Int -> Variance -> ShowS
$cshow :: Variance -> String
show :: Variance -> String
$cshowList :: [Variance] -> ShowS
showList :: [Variance] -> ShowS
Show)
defaultVariances :: Map Reference [Variance]
defaultVariances :: Map Reference [Variance]
defaultVariances =
[(Reference, [Variance])] -> Map Reference [Variance]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (Reference
listRef, [Variance
Pos]),
(Reference
iarrayRef, [Variance
Pos])
]
lookupVariance :: Map Reference [Variance] -> Type v a -> Maybe [Variance]
lookupVariance :: forall v a.
Map Reference [Variance] -> Type v a -> Maybe [Variance]
lookupVariance Map Reference [Variance]
vs (Ref' Reference
r) = Reference -> Map Reference [Variance] -> Maybe [Variance]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Reference
r Map Reference [Variance]
vs
lookupVariance Map Reference [Variance]
_ Term F v a
_ = Maybe [Variance]
forall a. Maybe a
Nothing
combine :: (Ord v) => [Map v [Polarity v]] -> Map v [Polarity v]
combine :: forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine [] = Map v [Polarity v]
forall k a. Map k a
Map.empty
combine (Map v [Polarity v]
m : [Map v [Polarity v]]
ms) = (Map v [Polarity v] -> Map v [Polarity v] -> Map v [Polarity v])
-> Map v [Polarity v] -> [Map v [Polarity v]] -> Map v [Polarity v]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (([Polarity v] -> [Polarity v] -> [Polarity v])
-> Map v [Polarity v] -> Map v [Polarity v] -> Map v [Polarity v]
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith [Polarity v] -> [Polarity v] -> [Polarity v]
forall a. [a] -> [a] -> [a]
(++)) Map v [Polarity v]
m [Map v [Polarity v]]
ms
collectVariance ::
(Var v) =>
Map Reference [Variance] ->
Map Reference [v] ->
Type v a ->
Map v [Polarity v]
collectVariance :: forall v a.
Var v =>
Map Reference [Variance]
-> Map Reference [v] -> Type v a -> Map v [Polarity v]
collectVariance Map Reference [Variance]
prev Map Reference [v]
group = Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
forall v. Polarity v
Positive
where
descend :: Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol = \case
Arrow' Term F v a
i Term F v a
o ->
([Polarity v] -> [Polarity v] -> [Polarity v])
-> Map v [Polarity v] -> Map v [Polarity v] -> Map v [Polarity v]
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith [Polarity v] -> [Polarity v] -> [Polarity v]
forall a. [a] -> [a] -> [a]
(++) (Polarity v -> Term F v a -> Map v [Polarity v]
descend (Polarity v -> Polarity v
forall v. Polarity v -> Polarity v
inv Polarity v
pol) Term F v a
i) (Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
o)
Effect1' Term F v a
e Term F v a
r ->
([Polarity v] -> [Polarity v] -> [Polarity v])
-> Map v [Polarity v] -> Map v [Polarity v] -> Map v [Polarity v]
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith [Polarity v] -> [Polarity v] -> [Polarity v]
forall a. [a] -> [a] -> [a]
(++) (Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
e) (Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
r)
Apps' Term F v a
f [Term F v a]
xs
| Ref' Reference
r <- Term F v a
f,
Just [v]
bnd <- Reference -> Map Reference [v] -> Maybe [v]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Reference
r Map Reference [v]
group ->
[Map v [Polarity v]] -> Map v [Polarity v]
forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine ([Map v [Polarity v]] -> Map v [Polarity v])
-> [Map v [Polarity v]] -> Map v [Polarity v]
forall a b. (a -> b) -> a -> b
$ (v -> Term F v a -> Map v [Polarity v])
-> [v] -> [Term F v a] -> [Map v [Polarity v]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Polarity v -> Term F v a -> Map v [Polarity v]
descend (Polarity v -> Term F v a -> Map v [Polarity v])
-> (v -> Polarity v) -> v -> Term F v a -> Map v [Polarity v]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Polarity v -> Polarity v -> Polarity v
forall v. Polarity v -> Polarity v -> Polarity v
act Polarity v
pol (Polarity v -> Polarity v) -> (v -> Polarity v) -> v -> Polarity v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v -> Polarity v
forall v. v -> Polarity v
As) [v]
bnd [Term F v a]
xs
| Just [Variance]
vs <- Map Reference [Variance] -> Term F v a -> Maybe [Variance]
forall v a.
Map Reference [Variance] -> Type v a -> Maybe [Variance]
lookupVariance Map Reference [Variance]
prev Term F v a
f ->
[Map v [Polarity v]] -> Map v [Polarity v]
forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine ([Map v [Polarity v]] -> Map v [Polarity v])
-> [Map v [Polarity v]] -> Map v [Polarity v]
forall a b. (a -> b) -> a -> b
$ Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
f Map v [Polarity v] -> [Map v [Polarity v]] -> [Map v [Polarity v]]
forall a. a -> [a] -> [a]
: (Variance -> Term F v a -> Map v [Polarity v])
-> [Variance] -> [Term F v a] -> [Map v [Polarity v]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Variance -> Term F v a -> Map v [Polarity v]
h [Variance]
vs [Term F v a]
xs
| Bool
otherwise -> [Map v [Polarity v]] -> Map v [Polarity v]
forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine ([Map v [Polarity v]] -> Map v [Polarity v])
-> [Map v [Polarity v]] -> Map v [Polarity v]
forall a b. (a -> b) -> a -> b
$ Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
f Map v [Polarity v] -> [Map v [Polarity v]] -> [Map v [Polarity v]]
forall a. a -> [a] -> [a]
: (Term F v a -> Map v [Polarity v])
-> [Term F v a] -> [Map v [Polarity v]]
forall a b. (a -> b) -> [a] -> [b]
map (Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
forall v. Polarity v
Exact) [Term F v a]
xs
where
h :: Variance -> Term F v a -> Map v [Polarity v]
h Variance
Any Term F v a
_ = Map v [Polarity v]
forall k a. Map k a
Map.empty
h Variance
Neg Term F v a
t = Polarity v -> Term F v a -> Map v [Polarity v]
descend (Polarity v -> Polarity v
forall v. Polarity v -> Polarity v
inv Polarity v
pol) Term F v a
t
h Variance
Pos Term F v a
t = Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
t
h Variance
Inv Term F v a
t = Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
forall v. Polarity v
Exact Term F v a
t
Ann' Term F v a
t Kind
_ -> Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
t
Effects' [Term F v a]
ts -> [Map v [Polarity v]] -> Map v [Polarity v]
forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine ([Map v [Polarity v]] -> Map v [Polarity v])
-> [Map v [Polarity v]] -> Map v [Polarity v]
forall a b. (a -> b) -> a -> b
$ (Term F v a -> Map v [Polarity v])
-> [Term F v a] -> [Map v [Polarity v]]
forall a b. (a -> b) -> [a] -> [b]
map (Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol) [Term F v a]
ts
ForallsNamed' [v]
_ Term F v a
t -> Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
t
IntroOuterNamed' v
_ Term F v a
t -> Polarity v -> Term F v a -> Map v [Polarity v]
descend Polarity v
pol Term F v a
t
Var' v
v -> v -> [Polarity v] -> Map v [Polarity v]
forall k a. k -> a -> Map k a
Map.singleton v
v [Polarity v
pol]
Term F v a
_ -> Map v [Polarity v]
forall k a. Map k a
Map.empty
collectDeclVariance ::
(Var v, Show a) =>
Map Reference [Variance] ->
Map Reference [v] ->
DataDeclaration v a ->
Map v [Polarity v]
collectDeclVariance :: forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference [v] -> DataDeclaration v a -> Map v [Polarity v]
collectDeclVariance Map Reference [Variance]
vars Map Reference [v]
group DataDeclaration v a
decl =
[Map v [Polarity v]] -> Map v [Polarity v]
forall v. Ord v => [Map v [Polarity v]] -> Map v [Polarity v]
combine ([Map v [Polarity v]] -> Map v [Polarity v])
-> [Map v [Polarity v]] -> Map v [Polarity v]
forall a b. (a -> b) -> a -> b
$
(Type v a -> Map v [Polarity v])
-> [Type v a] -> [Map v [Polarity v]]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Map Reference [Variance]
-> Map Reference [v] -> Type v a -> Map v [Polarity v]
forall v a.
Var v =>
Map Reference [Variance]
-> Map Reference [v] -> Type v a -> Map v [Polarity v]
collectVariance Map Reference [Variance]
vars Map Reference [v]
group)
([Type v a] -> [Map v [Polarity v]])
-> ((v, Type v a) -> [Type v a])
-> (v, Type v a)
-> [Map v [Polarity v]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v, Type v a) -> [Type v a]
forall {a} {v} {a}. (a, Type v a) -> [Type v a]
split
((v, Type v a) -> [Map v [Polarity v]])
-> [(v, Type v a)] -> [Map v [Polarity v]]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< DataDeclaration v a -> [(v, Type v a)]
forall v a. DataDeclaration v a -> [(v, Type v a)]
constructors DataDeclaration v a
decl
where
split :: (a, Type v a) -> [Type v a]
split (a
_, ForallsNamedOpt' [v]
_vs (Arrows' [Type v a]
ts)) = [Type v a]
ts
split (a
_, Type v a
t) = [Type v a
t]
simplify :: (Var v) => v -> [Polarity v] -> [Polarity v]
simplify :: forall v. Var v => v -> [Polarity v] -> [Polarity v]
simplify v
v = Set (Polarity v) -> [Polarity v]
reduce (Set (Polarity v) -> [Polarity v])
-> ([Polarity v] -> Set (Polarity v))
-> [Polarity v]
-> [Polarity v]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Polarity v -> Set (Polarity v) -> Set (Polarity v)
forall a. Ord a => a -> Set a -> Set a
Set.delete (v -> Polarity v
forall v. v -> Polarity v
As v
v) (Set (Polarity v) -> Set (Polarity v))
-> ([Polarity v] -> Set (Polarity v))
-> [Polarity v]
-> Set (Polarity v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Polarity v] -> Set (Polarity v)
forall a. Ord a => [a] -> Set a
Set.fromList
where
reduce :: Set (Polarity v) -> [Polarity v]
reduce Set (Polarity v)
s
| Polarity v
forall v. Polarity v
Exact Polarity v -> Set (Polarity v) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (Polarity v)
s = [Polarity v
forall v. Polarity v
Exact]
| Polarity v
forall v. Polarity v
Positive Polarity v -> Set (Polarity v) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (Polarity v)
s,
Polarity v
forall v. Polarity v
Negative Polarity v -> Set (Polarity v) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (Polarity v)
s =
[Polarity v
forall v. Polarity v
Exact]
| v -> Polarity v
forall v. v -> Polarity v
Op v
v Polarity v -> Set (Polarity v) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (Polarity v)
s = [Polarity v
forall v. Polarity v
Exact]
| Bool
otherwise = Set (Polarity v) -> [Polarity v]
forall a. Set a -> [a]
Set.toList Set (Polarity v)
s
chain :: (Var v) => Map v [Polarity v] -> [Polarity v] -> [Polarity v]
chain :: forall v.
Var v =>
Map v [Polarity v] -> [Polarity v] -> [Polarity v]
chain Map v [Polarity v]
m = (Polarity v -> [Polarity v]) -> [Polarity v] -> [Polarity v]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Polarity v -> [Polarity v]
f
where
f :: Polarity v -> [Polarity v]
f (As v
v) = [Polarity v] -> v -> Map v [Polarity v] -> [Polarity v]
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault [Polarity v
forall v. Polarity v
Exact] v
v Map v [Polarity v]
m
f (Op v
v) = Polarity v -> Polarity v
forall v. Polarity v -> Polarity v
inv (Polarity v -> Polarity v) -> [Polarity v] -> [Polarity v]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Polarity v] -> v -> Map v [Polarity v] -> [Polarity v]
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault [Polarity v
forall v. Polarity v
Exact] v
v Map v [Polarity v]
m
f Polarity v
p = [Polarity v
p]
checkFinished :: Map v [Polarity v] -> Maybe (Map v Variance)
checkFinished :: forall v. Map v [Polarity v] -> Maybe (Map v Variance)
checkFinished = ([Polarity v] -> Maybe Variance)
-> Map v [Polarity v] -> Maybe (Map v Variance)
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) -> Map v a -> f (Map v b)
traverse [Polarity v] -> Maybe Variance
forall {v}. [Polarity v] -> Maybe Variance
f
where
f :: [Polarity v] -> Maybe Variance
f [] = Variance -> Maybe Variance
forall a. a -> Maybe a
Just Variance
Any
f [Polarity v
Exact] = Variance -> Maybe Variance
forall a. a -> Maybe a
Just Variance
Inv
f [Polarity v
Positive] = Variance -> Maybe Variance
forall a. a -> Maybe a
Just Variance
Pos
f [Polarity v
Negative] = Variance -> Maybe Variance
forall a. a -> Maybe a
Just Variance
Neg
f [Polarity v]
_ = Maybe Variance
forall a. Maybe a
Nothing
solve :: (Var v) => Map v [Polarity v] -> Map v Variance
solve :: forall v. Var v => Map v [Polarity v] -> Map v Variance
solve Map v [Polarity v]
map0
| Just Map v Variance
m <- Map v [Polarity v] -> Maybe (Map v Variance)
forall v. Map v [Polarity v] -> Maybe (Map v Variance)
checkFinished Map v [Polarity v]
map0 = Map v Variance
m
| Bool
otherwise = Map v [Polarity v] -> Map v Variance
forall v. Var v => Map v [Polarity v] -> Map v Variance
solve (Map v [Polarity v] -> Map v Variance)
-> (Map v [Polarity v] -> Map v [Polarity v])
-> Map v [Polarity v]
-> Map v Variance
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> [Polarity v] -> [Polarity v])
-> Map v [Polarity v] -> Map v [Polarity v]
forall k a b. (k -> a -> b) -> Map k a -> Map k b
Map.mapWithKey v -> [Polarity v] -> [Polarity v]
forall v. Var v => v -> [Polarity v] -> [Polarity v]
simplify (Map v [Polarity v] -> Map v Variance)
-> Map v [Polarity v] -> Map v Variance
forall a b. (a -> b) -> a -> b
$ Map v [Polarity v] -> [Polarity v] -> [Polarity v]
forall v.
Var v =>
Map v [Polarity v] -> [Polarity v] -> [Polarity v]
chain Map v [Polarity v]
map0 ([Polarity v] -> [Polarity v])
-> Map v [Polarity v] -> Map v [Polarity v]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map v [Polarity v]
map0
inferDeclGroupVariance ::
(Var v, Show a) =>
Map Reference [Variance] ->
Map Reference (DataDeclaration v a) ->
Map Reference [Variance]
inferDeclGroupVariance :: forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
inferDeclGroupVariance Map Reference [Variance]
vars (Map Reference (DataDeclaration v a)
-> Map Reference ([v], DataDeclaration v a)
forall v a.
Var v =>
Map Reference (DataDeclaration v a)
-> Map Reference ([v], DataDeclaration v a)
freshenGroup -> Map Reference ([v], DataDeclaration v a)
group) =
Map v Variance -> Map Reference [Variance]
resolveGroup (Map v Variance -> Map Reference [Variance])
-> (Map v [Polarity v] -> Map v Variance)
-> Map v [Polarity v]
-> Map Reference [Variance]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map v [Polarity v] -> Map v Variance
forall v. Var v => Map v [Polarity v] -> Map v Variance
solve (Map v [Polarity v] -> Map Reference [Variance])
-> Map v [Polarity v] -> Map Reference [Variance]
forall a b. (a -> b) -> a -> b
$
(([v], DataDeclaration v a) -> Map v [Polarity v])
-> Map Reference ([v], DataDeclaration v a) -> Map v [Polarity v]
forall m a. Monoid m => (a -> m) -> Map Reference a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Map Reference [Variance]
-> Map Reference [v] -> DataDeclaration v a -> Map v [Polarity v]
forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference [v] -> DataDeclaration v a -> Map v [Polarity v]
collectDeclVariance Map Reference [Variance]
vars Map Reference [v]
groupVars (DataDeclaration v a -> Map v [Polarity v])
-> (([v], DataDeclaration v a) -> DataDeclaration v a)
-> ([v], DataDeclaration v a)
-> Map v [Polarity v]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([v], DataDeclaration v a) -> DataDeclaration v a
forall a b. (a, b) -> b
snd) Map Reference ([v], DataDeclaration v a)
group
where
groupVars :: Map Reference [v]
groupVars = ([v], DataDeclaration v a) -> [v]
forall a b. (a, b) -> a
fst (([v], DataDeclaration v a) -> [v])
-> Map Reference ([v], DataDeclaration v a) -> Map Reference [v]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Reference ([v], DataDeclaration v a)
group
resolveGroup :: Map v Variance -> Map Reference [Variance]
resolveGroup Map v Variance
m = (([v], DataDeclaration v a) -> Maybe [Variance])
-> Map Reference ([v], DataDeclaration v a)
-> Map Reference [Variance]
forall a b k. (a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybe (Map v Variance -> [v] -> Maybe [Variance]
forall {t :: * -> *} {k} {b}.
(Traversable t, Ord k) =>
Map k b -> t k -> Maybe (t b)
resolve Map v Variance
m ([v] -> Maybe [Variance])
-> (([v], DataDeclaration v a) -> [v])
-> ([v], DataDeclaration v a)
-> Maybe [Variance]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([v], DataDeclaration v a) -> [v]
forall a b. (a, b) -> a
fst) Map Reference ([v], DataDeclaration v a)
group
resolve :: Map k b -> t k -> Maybe (t b)
resolve Map k b
m t k
bound = (k -> Maybe b) -> t k -> Maybe (t b)
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) -> t a -> f (t b)
traverse (\k
v -> k -> Map k b -> Maybe b
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
v Map k b
m) t k
bound
freshenGroup ::
(Var v) =>
Map Reference (DataDeclaration v a) ->
Map Reference ([v], DataDeclaration v a)
freshenGroup :: forall v a.
Var v =>
Map Reference (DataDeclaration v a)
-> Map Reference ([v], DataDeclaration v a)
freshenGroup Map Reference (DataDeclaration v a)
group = State (Set v) (Map Reference ([v], DataDeclaration v a))
-> Set v -> Map Reference ([v], DataDeclaration v a)
forall s a. State s a -> s -> a
evalState ((DataDeclaration v a
-> StateT (Set v) Identity ([v], DataDeclaration v a))
-> Map Reference (DataDeclaration v a)
-> State (Set v) (Map Reference ([v], DataDeclaration v a))
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) -> Map Reference a -> f (Map Reference b)
traverse DataDeclaration v a
-> StateT (Set v) Identity ([v], DataDeclaration v a)
forall v a.
Var v =>
DataDeclaration v a -> State (Set v) ([v], DataDeclaration v a)
freshDecl Map Reference (DataDeclaration v a)
group) Set v
forall a. Set a
Set.empty
freshDecl ::
(Var v) =>
DataDeclaration v a ->
State (Set.Set v) ([v], DataDeclaration v a)
freshDecl :: forall v a.
Var v =>
DataDeclaration v a -> State (Set v) ([v], DataDeclaration v a)
freshDecl DataDeclaration v a
dd = do
[v]
vs <- (v -> StateT (Set v) Identity v)
-> [v] -> StateT (Set v) Identity [v]
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 v -> StateT (Set v) Identity v
forall {a} {m :: * -> *}. (MonadState (Set a) m, Var a) => a -> m a
fv (DataDeclaration v a -> [v]
forall v a. DataDeclaration v a -> [v]
bound DataDeclaration v a
dd)
let frvs :: Map v v
frvs = [(v, v)] -> Map v v
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(v, v)] -> Map v v) -> [(v, v)] -> Map v v
forall a b. (a -> b) -> a -> b
$ [v] -> [v] -> [(v, v)]
forall a b. [a] -> [b] -> [(a, b)]
zip (DataDeclaration v a -> [v]
forall v a. DataDeclaration v a -> [v]
bound DataDeclaration v a
dd) [v]
vs
f :: v -> v
f v
v = v -> v -> Map v v -> v
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault v
v v
v Map v v
frvs
([v], DataDeclaration v a)
-> State (Set v) ([v], DataDeclaration v a)
forall a. a -> StateT (Set v) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([v]
vs, (v -> v) -> DataDeclaration v a -> DataDeclaration v a
forall v' v a.
Ord v' =>
(v -> v') -> DataDeclaration v a -> DataDeclaration v' a
vmap' v -> v
f DataDeclaration v a
dd)
where
fv :: a -> m a
fv a
u = (Set a -> (a, Set a)) -> m a
forall a. (Set a -> (a, Set a)) -> m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state \Set a
avoid ->
let v :: a
v = Set a -> a -> a
forall v. Var v => Set v -> v -> v
freshIn Set a
avoid a
u
in (a
v, a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
v Set a
avoid)
inferDeclVariances ::
(Var v, Show a) =>
Map Reference [Variance] ->
Map Reference (DataDeclaration v a) ->
Map Reference [Variance]
inferDeclVariances :: forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
inferDeclVariances Map Reference [Variance]
boot (Map Reference (DataDeclaration v a)
-> [(Reference, DataDeclaration v a)]
forall k a. Map k a -> [(k, a)]
Map.toList -> [(Reference, DataDeclaration v a)]
rdds) =
State (Map Reference [Variance]) ()
-> Map Reference [Variance] -> Map Reference [Variance]
forall s a. State s a -> s -> s
execState ((SCC (Reference, DataDeclaration v a)
-> State (Map Reference [Variance]) ())
-> [SCC (Reference, DataDeclaration v a)]
-> State (Map Reference [Variance]) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ SCC (Reference, DataDeclaration v a)
-> State (Map Reference [Variance]) ()
forall {m :: * -> *} {v} {a}.
(MonadState (Map Reference [Variance]) m, Var v, Show a) =>
SCC (Reference, DataDeclaration v a) -> m ()
inf [SCC (Reference, DataDeclaration v a)]
sccs) Map Reference [Variance]
boot
where
inf :: SCC (Reference, DataDeclaration v a) -> m ()
inf ([(Reference, DataDeclaration v a)]
-> Map Reference (DataDeclaration v a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Reference, DataDeclaration v a)]
-> Map Reference (DataDeclaration v a))
-> (SCC (Reference, DataDeclaration v a)
-> [(Reference, DataDeclaration v a)])
-> SCC (Reference, DataDeclaration v a)
-> Map Reference (DataDeclaration v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SCC (Reference, DataDeclaration v a)
-> [(Reference, DataDeclaration v a)]
forall vertex. SCC vertex -> [vertex]
flattenSCC -> Map Reference (DataDeclaration v a)
ddm) = do
Map Reference [Variance]
vs <- m (Map Reference [Variance])
forall s (m :: * -> *). MonadState s m => m s
get
Map Reference [Variance] -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (Map Reference [Variance] -> m ())
-> (Map Reference [Variance] -> Map Reference [Variance])
-> Map Reference [Variance]
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Reference [Variance]
-> Map Reference [Variance] -> Map Reference [Variance]
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map Reference [Variance]
vs (Map Reference [Variance] -> m ())
-> Map Reference [Variance] -> m ()
forall a b. (a -> b) -> a -> b
$ Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
inferDeclGroupVariance Map Reference [Variance]
vs Map Reference (DataDeclaration v a)
ddm
trc :: (b, DataDeclaration v a)
-> ((b, DataDeclaration v a), b, [Reference])
trc p :: (b, DataDeclaration v a)
p@(b
r, DataDeclaration v a
dd) = ((b, DataDeclaration v a)
p, b
r, Set Reference -> [Reference]
forall a. Set a -> [a]
Set.toList (Set Reference -> [Reference]) -> Set Reference -> [Reference]
forall a b. (a -> b) -> a -> b
$ DataDeclaration v a -> Set Reference
forall v a. Ord v => DataDeclaration v a -> Set Reference
typeDependencies DataDeclaration v a
dd)
sccs :: [SCC (Reference, DataDeclaration v a)]
sccs = [((Reference, DataDeclaration v a), Reference, [Reference])]
-> [SCC (Reference, DataDeclaration v a)]
forall key node. Ord key => [(node, key, [key])] -> [SCC node]
stronglyConnComp ([((Reference, DataDeclaration v a), Reference, [Reference])]
-> [SCC (Reference, DataDeclaration v a)])
-> [((Reference, DataDeclaration v a), Reference, [Reference])]
-> [SCC (Reference, DataDeclaration v a)]
forall a b. (a -> b) -> a -> b
$ ((Reference, DataDeclaration v a)
-> ((Reference, DataDeclaration v a), Reference, [Reference]))
-> [(Reference, DataDeclaration v a)]
-> [((Reference, DataDeclaration v a), Reference, [Reference])]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Reference, DataDeclaration v a)
-> ((Reference, DataDeclaration v a), Reference, [Reference])
forall {v} {b} {a}.
Ord v =>
(b, DataDeclaration v a)
-> ((b, DataDeclaration v a), b, [Reference])
trc [(Reference, DataDeclaration v a)]
rdds
fromTypeLookup ::
(Var v, Show a) => TypeLookup v a -> Map Reference [Variance]
fromTypeLookup :: forall v a.
(Var v, Show a) =>
TypeLookup v a -> Map Reference [Variance]
fromTypeLookup = Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
forall v a.
(Var v, Show a) =>
Map Reference [Variance]
-> Map Reference (DataDeclaration v a) -> Map Reference [Variance]
inferDeclVariances Map Reference [Variance]
defaultVariances (Map Reference (DataDeclaration v a) -> Map Reference [Variance])
-> (TypeLookup v a -> Map Reference (DataDeclaration v a))
-> TypeLookup v a
-> Map Reference [Variance]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeLookup v a -> Map Reference (DataDeclaration v a)
forall v a. TypeLookup v a -> Map Reference (DataDeclaration v a)
dataDecls