{-# LANGUAGE LambdaCase #-}
module Clash.Hedgehog.Core.TyCon
( genTyConMap
) where
import Control.Monad (forM)
import Data.Coerce (coerce)
import Data.Either (rights)
import Hedgehog (Range)
import qualified Hedgehog.Gen as Gen
import Clash.Core.DataCon
import Clash.Core.HasType
import Clash.Core.Name (nameUniq)
import Clash.Core.Subst
import Clash.Core.TyCon
import Clash.Core.Type (Kind, Type(VarTy), mkTyConApp, splitFunForallTy)
import Clash.Core.TysPrim (liftedTypeKind, tysPrimMap)
import Clash.Core.Var
import Clash.Core.VarEnv
import Clash.Unique
import Clash.Hedgehog.Core.DataCon
import Clash.Hedgehog.Core.Monad
import Clash.Hedgehog.Core.Name
import Clash.Hedgehog.Core.Type
import Clash.Hedgehog.Core.Var
import Clash.Hedgehog.Unique
arityOf :: Kind -> Int
arityOf :: Kind -> Int
arityOf = [Either TyVar Kind] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length ([Either TyVar Kind] -> Int)
-> (Kind -> [Either TyVar Kind]) -> Kind -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Either TyVar Kind], Kind) -> [Either TyVar Kind]
forall a b. (a, b) -> a
fst (([Either TyVar Kind], Kind) -> [Either TyVar Kind])
-> (Kind -> ([Either TyVar Kind], Kind))
-> Kind
-> [Either TyVar Kind]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Kind -> ([Either TyVar Kind], Kind)
splitFunForallTy
genTyConMap
:: forall m
. (Alternative m, MonadGen m)
=> Range Int
-> CoreGenT m TyConMap
genTyConMap :: Range Int -> CoreGenT m TyConMap
genTyConMap Range Int
numDcs = TyConMap -> CoreGenT m TyConMap
go TyConMap
tysPrimMap
where
go :: TyConMap -> CoreGenT m TyConMap
go TyConMap
tcm =
([CoreGenT m TyConMap] -> CoreGenT m TyConMap)
-> [CoreGenT m TyConMap]
-> [CoreGenT m TyConMap]
-> CoreGenT m TyConMap
forall (m :: Type -> Type) a.
MonadGen m =>
([m a] -> m a) -> [m a] -> [m a] -> m a
Gen.recursive [CoreGenT m TyConMap] -> CoreGenT m TyConMap
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice
[TyConMap -> CoreGenT m TyConMap
forall (m :: Type -> Type) a. MonadGen m => a -> m a
Gen.constant TyConMap
tcm]
[CoreGenT m TyConMap
-> (TyConMap -> CoreGenT m TyConMap) -> CoreGenT m TyConMap
forall (m :: Type -> Type) a.
MonadGen m =>
m a -> (a -> m a) -> m a
Gen.subtermM (TyConMap -> CoreGenT m TyConMap
extendTyConMap TyConMap
tcm) TyConMap -> CoreGenT m TyConMap
go]
extendTyConMap :: TyConMap -> CoreGenT m TyConMap
extendTyConMap TyConMap
tcm = do
TyConMap
new <- CoreGenT m Bool
forall (m :: Type -> Type). Monad m => CoreGenT m Bool
canGenTypeFamilies CoreGenT m Bool
-> (Bool -> CoreGenT m TyConMap) -> CoreGenT m TyConMap
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> [CoreGenT m TyConMap] -> CoreGenT m TyConMap
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice
[ Range Int -> TyConMap -> CoreGenT m TyConMap
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
Range Int -> TyConMap -> CoreGenT m TyConMap
genAlgTyConFrom Range Int
numDcs TyConMap
tcm
, TyConMap -> CoreGenT m TyConMap
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> CoreGenT m TyConMap
genFunTyConFrom TyConMap
tcm CoreGenT m TyConMap -> CoreGenT m TyConMap -> CoreGenT m TyConMap
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> Range Int -> TyConMap -> CoreGenT m TyConMap
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
Range Int -> TyConMap -> CoreGenT m TyConMap
genAlgTyConFrom Range Int
numDcs TyConMap
tcm
]
Bool
False -> [CoreGenT m TyConMap] -> CoreGenT m TyConMap
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice [Range Int -> TyConMap -> CoreGenT m TyConMap
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
Range Int -> TyConMap -> CoreGenT m TyConMap
genAlgTyConFrom Range Int
numDcs TyConMap
tcm]
TyConMap -> CoreGenT m TyConMap
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TyConMap -> TyConMap -> TyConMap
forall a. UniqMap a -> UniqMap a -> UniqMap a
unionUniqMap TyConMap
tcm TyConMap
new)
genAlgTyConFrom
:: forall m
. (Alternative m, MonadGen m)
=> Range Int
-> TyConMap
-> CoreGenT m TyConMap
genAlgTyConFrom :: Range Int -> TyConMap -> CoreGenT m TyConMap
genAlgTyConFrom Range Int
range TyConMap
tcm = do
let used :: UniqSet Int
used = UniqMap Int -> UniqSet Int
forall a. UniqMap a -> UniqSet a
uniqMapToUniqSet ((TyCon -> Int) -> TyConMap -> UniqMap Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap TyCon -> Int
tyConUniq TyConMap
tcm)
Name TyCon
name <- UniqSet Int -> CoreGenT m (Name TyCon) -> CoreGenT m (Name TyCon)
forall (m :: Type -> Type) a b.
MonadGen m =>
UniqSet b -> m (Name a) -> m (Name a)
genFreshName UniqSet Int
used CoreGenT m (Name TyCon)
forall (m :: Type -> Type). MonadGen m => m (Name TyCon)
genTyConName
let kn :: Kind
kn = Kind
liftedTypeKind
let arity :: Int
arity = Kind -> Int
arityOf Kind
kn
AlgTyConRhs
rhs <- [CoreGenT m AlgTyConRhs] -> CoreGenT m AlgTyConRhs
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice
[ [DataCon] -> AlgTyConRhs
DataTyCon ([DataCon] -> AlgTyConRhs)
-> CoreGenT m [DataCon] -> CoreGenT m AlgTyConRhs
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Int -> TyConMap -> Name TyCon -> Kind -> CoreGenT m [DataCon]
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
Range Int -> TyConMap -> Name TyCon -> Kind -> CoreGenT m [DataCon]
genDataConsFrom Range Int
range TyConMap
tcm Name TyCon
name Kind
kn
]
let tc :: TyCon
tc = Int -> Name TyCon -> Kind -> Int -> AlgTyConRhs -> Bool -> TyCon
AlgTyCon (Name TyCon -> Int
forall a. Name a -> Int
nameUniq Name TyCon
name) Name TyCon
name Kind
kn Int
arity AlgTyConRhs
rhs Bool
False
CoreGenT m Bool
forall (m :: Type -> Type). Monad m => CoreGenT m Bool
canGenDataKinds CoreGenT m Bool
-> (Bool -> CoreGenT m TyConMap) -> CoreGenT m TyConMap
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True ->
let dcs :: [DataCon]
dcs = TyCon -> [DataCon]
tyConDataCons TyCon
tc
in TyConMap -> CoreGenT m TyConMap
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([(Name TyCon, TyCon)] -> TyConMap
forall a b. Uniquable a => [(a, b)] -> UniqMap b
listToUniqMap ((Name TyCon
name, TyCon
tc) (Name TyCon, TyCon)
-> [(Name TyCon, TyCon)] -> [(Name TyCon, TyCon)]
forall a. a -> [a] -> [a]
: (DataCon -> (Name TyCon, TyCon))
-> [DataCon] -> [(Name TyCon, TyCon)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap DataCon -> (Name TyCon, TyCon)
promoteDataCon [DataCon]
dcs))
Bool
False ->
TyConMap -> CoreGenT m TyConMap
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Name TyCon -> TyCon -> TyConMap
forall a b. Uniquable a => a -> b -> UniqMap b
unitUniqMap Name TyCon
name TyCon
tc)
where
promoteDataCon :: DataCon -> (Name TyCon, TyCon)
promoteDataCon DataCon
dc =
let tcn :: Name TyCon
tcn = DcName -> Name TyCon
coerce (DataCon -> DcName
dcName DataCon
dc)
arity :: Int
arity = Kind -> Int
arityOf (DataCon -> Kind
dcType DataCon
dc)
in (Name TyCon
tcn, Int -> Name TyCon -> Kind -> Int -> DataCon -> TyCon
PromotedDataCon (DataCon -> Int
dcUniq DataCon
dc) Name TyCon
tcn (DataCon -> Kind
dcType DataCon
dc) Int
arity DataCon
dc)
genFunTyConFrom
:: forall m
. (Alternative m, MonadGen m)
=> TyConMap
-> CoreGenT m TyConMap
genFunTyConFrom :: TyConMap -> CoreGenT m TyConMap
genFunTyConFrom TyConMap
tcm = do
let used :: UniqSet Int
used = UniqMap Int -> UniqSet Int
forall a. UniqMap a -> UniqSet a
uniqMapToUniqSet ((TyCon -> Int) -> TyConMap -> UniqMap Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap TyCon -> Int
tyConUniq TyConMap
tcm)
Name TyCon
name <- UniqSet Int -> CoreGenT m (Name TyCon) -> CoreGenT m (Name TyCon)
forall (m :: Type -> Type) a b.
MonadGen m =>
UniqSet b -> m (Name a) -> m (Name a)
genFreshName UniqSet Int
used CoreGenT m (Name TyCon)
forall (m :: Type -> Type). MonadGen m => m (Name TyCon)
genTyConName
Kind
kn <- TyConMap -> Kind -> CoreGenT m Kind
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> Kind -> CoreGenT m Kind
genClosedKindFrom TyConMap
tcm Kind
liftedTypeKind
let arity :: Int
arity = Kind -> Int
arityOf Kind
kn
let ([Either TyVar Kind]
argKns, Kind
resKn) = Kind -> ([Either TyVar Kind], Kind)
splitFunForallTy Kind
kn
[([Kind], Kind)]
substs <- Name TyCon -> [Kind] -> Kind -> CoreGenT m [([Kind], Kind)]
genSubsts Name TyCon
name ([Either TyVar Kind] -> [Kind]
forall a b. [Either a b] -> [b]
rights [Either TyVar Kind]
argKns) Kind
resKn
let tc :: TyCon
tc = Int -> Name TyCon -> Kind -> Int -> [([Kind], Kind)] -> TyCon
FunTyCon (Name TyCon -> Int
forall a. Name a -> Int
nameUniq Name TyCon
name) Name TyCon
name Kind
kn Int
arity [([Kind], Kind)]
substs
TyConMap -> CoreGenT m TyConMap
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Name TyCon -> TyCon -> TyConMap
forall a b. Uniquable a => a -> b -> UniqMap b
unitUniqMap Name TyCon
name TyCon
tc)
where
genSubsts :: TyConName -> [Kind] -> Kind -> CoreGenT m [([Type], Type)]
genSubsts :: Name TyCon -> [Kind] -> Kind -> CoreGenT m [([Kind], Kind)]
genSubsts Name TyCon
_ [] Kind
rhsKn = do
let tcm' :: TyConMap
tcm' = (TyCon -> Bool) -> TyConMap -> TyConMap
forall b. (b -> Bool) -> UniqMap b -> UniqMap b
filterUniqMap (Bool -> Bool
not (Bool -> Bool) -> (TyCon -> Bool) -> TyCon -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> Bool
isPrimTc) TyConMap
tcm
Kind
rhs <- TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
genMonoTypeFrom TyConMap
tcm' UniqMap TyVar
forall a. UniqMap a
emptyUniqMap Kind
rhsKn
[([Kind], Kind)] -> CoreGenT m [([Kind], Kind)]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure [([], Kind
rhs)]
genSubsts Name TyCon
name [Kind]
argKns Kind
rhsKn = do
let tcm' :: TyConMap
tcm' = (TyCon -> Bool) -> TyConMap -> TyConMap
forall b. (b -> Bool) -> UniqMap b -> UniqMap b
filterUniqMap (Bool -> Bool
not (Bool -> Bool) -> (TyCon -> Bool) -> TyCon -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> Bool
isPrimTc) TyConMap
tcm
[TyVar]
tvs <- (Kind -> CoreGenT m (Name Kind) -> CoreGenT m TyVar)
-> [Kind] -> CoreGenT m (Name Kind) -> CoreGenT m [TyVar]
forall (m :: Type -> Type) a.
MonadGen m =>
(Kind -> m (Name a) -> m (Var a))
-> [Kind] -> m (Name a) -> m [Var a]
genVars Kind -> CoreGenT m (Name Kind) -> CoreGenT m TyVar
forall (m :: Type -> Type).
MonadGen m =>
Kind -> m (Name Kind) -> m TyVar
genTyVar [Kind]
argKns CoreGenT m (Name Kind)
forall (m :: Type -> Type) a. MonadGen m => m (Name a)
genVarName
let acc :: [(UniqMap TyVar, Kind)]
acc = (TyVar -> (UniqMap TyVar, Kind))
-> [TyVar] -> [(UniqMap TyVar, Kind)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (\TyVar
x -> (TyVar -> TyVar -> UniqMap TyVar
forall a b. Uniquable a => a -> b -> UniqMap b
unitUniqMap TyVar
x TyVar
x, TyVar -> Kind
VarTy TyVar
x)) [TyVar]
tvs
[[(UniqMap TyVar, Kind)]]
lhss <- TyConMap
-> [(UniqMap TyVar, Kind)] -> CoreGenT m [[(UniqMap TyVar, Kind)]]
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> [(UniqMap TyVar, Kind)] -> m [[(UniqMap TyVar, Kind)]]
refineArgs TyConMap
tcm [(UniqMap TyVar, Kind)]
acc
[[(UniqMap TyVar, Kind)]]
-> ([(UniqMap TyVar, Kind)] -> CoreGenT m ([Kind], Kind))
-> CoreGenT m [([Kind], Kind)]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [[(UniqMap TyVar, Kind)]]
lhss (([(UniqMap TyVar, Kind)] -> CoreGenT m ([Kind], Kind))
-> CoreGenT m [([Kind], Kind)])
-> ([(UniqMap TyVar, Kind)] -> CoreGenT m ([Kind], Kind))
-> CoreGenT m [([Kind], Kind)]
forall a b. (a -> b) -> a -> b
$ \[(UniqMap TyVar, Kind)]
args -> do
let free :: UniqMap TyVar
free = [UniqMap TyVar] -> UniqMap TyVar
forall a. Monoid a => [a] -> a
mconcat (((UniqMap TyVar, Kind) -> UniqMap TyVar)
-> [(UniqMap TyVar, Kind)] -> [UniqMap TyVar]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (UniqMap TyVar, Kind) -> UniqMap TyVar
forall a b. (a, b) -> a
fst [(UniqMap TyVar, Kind)]
args)
Kind
rhs <- CoreGenT m Bool
forall (m :: Type -> Type). Monad m => CoreGenT m Bool
canGenUndecidableInstances CoreGenT m Bool -> (Bool -> CoreGenT m Kind) -> CoreGenT m Kind
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> [CoreGenT m Kind] -> CoreGenT m Kind
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice
[ TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
genMonoTypeFrom TyConMap
tcm' UniqMap TyVar
free Kind
rhsKn
, Name TyCon -> [Kind] -> Kind
mkTyConApp Name TyCon
name
([Kind] -> Kind) -> CoreGenT m [Kind] -> CoreGenT m Kind
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Kind -> CoreGenT m Kind) -> [Kind] -> CoreGenT m [Kind]
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
genMonoTypeFrom TyConMap
tcm' UniqMap TyVar
free) [Kind]
argKns
]
Bool
False -> TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> UniqMap TyVar -> Kind -> CoreGenT m Kind
genMonoTypeFrom TyConMap
tcm' UniqMap TyVar
free Kind
rhsKn
([Kind], Kind) -> CoreGenT m ([Kind], Kind)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (((UniqMap TyVar, Kind) -> Kind)
-> [(UniqMap TyVar, Kind)] -> [Kind]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (UniqMap TyVar, Kind) -> Kind
forall a b. (a, b) -> b
snd [(UniqMap TyVar, Kind)]
args, Kind
rhs)
refineArgs
:: forall m
. (Alternative m, MonadGen m)
=> TyConMap
-> [(UniqMap TyVar, Type)]
-> m [[(UniqMap TyVar, Type)]]
refineArgs :: TyConMap -> [(UniqMap TyVar, Kind)] -> m [[(UniqMap TyVar, Kind)]]
refineArgs TyConMap
tcm [(UniqMap TyVar, Kind)]
args = [[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
go [[(UniqMap TyVar, Kind)]
args]
where
go :: [[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
go [[(UniqMap TyVar, Kind)]]
acc =
([m [[(UniqMap TyVar, Kind)]]] -> m [[(UniqMap TyVar, Kind)]])
-> [m [[(UniqMap TyVar, Kind)]]]
-> [m [[(UniqMap TyVar, Kind)]]]
-> m [[(UniqMap TyVar, Kind)]]
forall (m :: Type -> Type) a.
MonadGen m =>
([m a] -> m a) -> [m a] -> [m a] -> m a
Gen.recursive [m [[(UniqMap TyVar, Kind)]]] -> m [[(UniqMap TyVar, Kind)]]
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice
[[[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
forall (m :: Type -> Type) a. MonadGen m => a -> m a
Gen.constant [[(UniqMap TyVar, Kind)]]
acc]
[m [[(UniqMap TyVar, Kind)]]
-> ([[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]])
-> m [[(UniqMap TyVar, Kind)]]
forall (m :: Type -> Type) a.
MonadGen m =>
m a -> (a -> m a) -> m a
Gen.subtermM ([[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
refineAgain [[(UniqMap TyVar, Kind)]]
acc) [[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
go]
refineAgain :: [[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
refineAgain acc :: [[(UniqMap TyVar, Kind)]]
acc@([(UniqMap TyVar, Kind)]
xs:[[(UniqMap TyVar, Kind)]]
_) = do
let gen :: (UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
gen (UniqMap TyVar, Kind)
x = [m (UniqMap TyVar, Kind)] -> m (UniqMap TyVar, Kind)
forall (m :: Type -> Type) a. MonadGen m => [m a] -> m a
Gen.choice [(UniqMap TyVar -> Kind -> m (UniqMap TyVar, Kind))
-> (UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (TyConMap -> UniqMap TyVar -> Kind -> m (UniqMap TyVar, Kind)
forall (m :: Type -> Type).
(Alternative m, MonadGen m) =>
TyConMap -> UniqMap TyVar -> Kind -> m (UniqMap TyVar, Kind)
refineArg TyConMap
tcm) (UniqMap TyVar, Kind)
x, (UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
forall (m :: Type -> Type) a. MonadGen m => a -> m a
Gen.constant (UniqMap TyVar, Kind)
x]
[(UniqMap TyVar, Kind)]
refined <- ((UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind))
-> [(UniqMap TyVar, Kind)] -> m [(UniqMap TyVar, Kind)]
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
gen [(UniqMap TyVar, Kind)]
xs
[[(UniqMap TyVar, Kind)]] -> m [[(UniqMap TyVar, Kind)]]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([(UniqMap TyVar, Kind)]
refined [(UniqMap TyVar, Kind)]
-> [[(UniqMap TyVar, Kind)]] -> [[(UniqMap TyVar, Kind)]]
forall a. a -> [a] -> [a]
: [[(UniqMap TyVar, Kind)]]
acc)
refineAgain [] =
[Char] -> m [[(UniqMap TyVar, Kind)]]
forall a. HasCallStack => [Char] -> a
error [Char]
"refineArgs: No types to refine."
refineArg
:: forall m
. (Alternative m, MonadGen m)
=> TyConMap
-> UniqMap TyVar
-> Type
-> m (UniqMap TyVar, Type)
refineArg :: TyConMap -> UniqMap TyVar -> Kind -> m (UniqMap TyVar, Kind)
refineArg TyConMap
tcm UniqMap TyVar
free Kind
ty
| UniqMap TyVar -> Bool
forall a. UniqMap a -> Bool
nullUniqMap UniqMap TyVar
free
= (UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (UniqMap TyVar
free, Kind
ty)
| Bool
otherwise
= do
TyVar
fv <- (TyVar, [Kind]) -> TyVar
forall a b. (a, b) -> a
fst ((TyVar, [Kind]) -> TyVar) -> m (TyVar, [Kind]) -> m TyVar
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> UniqMap TyVar -> m (TyVar, [Kind])
forall (m :: Type -> Type) v.
(Alternative m, MonadGen m, HasType v) =>
UniqMap v -> m (v, [Kind])
sampleAnyUniqMap UniqMap TyVar
free
let free' :: UniqMap TyVar
free' = UniqMap TyVar -> TyVar -> UniqMap TyVar
forall a b. Uniquable a => UniqMap b -> a -> UniqMap b
delUniqMap UniqMap TyVar
free TyVar
fv
(TyCon
tc, [Kind]
holes) <- (TyCon -> Bool) -> Kind -> TyConMap -> m (TyCon, [Kind])
forall (m :: Type -> Type) v.
(Alternative m, MonadGen m, HasType v, Bias v) =>
(v -> Bool) -> Kind -> UniqMap v -> m (v, [Kind])
sampleUniqMapBiased (Bool -> Bool
not (Bool -> Bool) -> (TyCon -> Bool) -> TyCon -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> Bool
isPrimTc) (TyVar -> Kind
forall a. HasType a => a -> Kind
coreTypeOf TyVar
fv) TyConMap
tcm
[TyVar]
holeVars <- (Kind -> m (Name Kind) -> m TyVar)
-> [Kind] -> m (Name Kind) -> m [TyVar]
forall (m :: Type -> Type) a.
MonadGen m =>
(Kind -> m (Name a) -> m (Var a))
-> [Kind] -> m (Name a) -> m [Var a]
genVars Kind -> m (Name Kind) -> m TyVar
forall (m :: Type -> Type).
MonadGen m =>
Kind -> m (Name Kind) -> m TyVar
genTyVar [Kind]
holes m (Name Kind)
forall (m :: Type -> Type) a. MonadGen m => m (Name a)
genVarName
let free'' :: UniqMap TyVar
free'' = UniqMap TyVar -> [(TyVar, TyVar)] -> UniqMap TyVar
forall a b. Uniquable a => UniqMap b -> [(a, b)] -> UniqMap b
extendListUniqMap UniqMap TyVar
free' ([TyVar] -> [TyVar] -> [(TyVar, TyVar)]
forall a b. [a] -> [b] -> [(a, b)]
zip [TyVar]
holeVars [TyVar]
holeVars)
let inScope :: InScopeSet
inScope = InScopeSet -> [TyVar] -> InScopeSet
forall a. InScopeSet -> [Var a] -> InScopeSet
extendInScopeSetList InScopeSet
emptyInScopeSet (UniqMap TyVar -> [TyVar]
forall a. UniqMap a -> [a]
eltsUniqMap UniqMap TyVar
free'')
let substTv :: VarEnv Kind
substTv = TyVar -> Kind -> VarEnv Kind
forall b a. Var b -> a -> VarEnv a
unitVarEnv TyVar
fv (Name TyCon -> [Kind] -> Kind
mkTyConApp (TyCon -> Name TyCon
tyConName TyCon
tc) ((TyVar -> Kind) -> [TyVar] -> [Kind]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap TyVar -> Kind
VarTy [TyVar]
holeVars))
let subst :: Subst
subst = InScopeSet -> VarEnv Kind -> Subst
mkTvSubst InScopeSet
inScope VarEnv Kind
substTv
(UniqMap TyVar, Kind) -> m (UniqMap TyVar, Kind)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (UniqMap TyVar
free'', HasCallStack => Subst -> Kind -> Kind
Subst -> Kind -> Kind
substTy Subst
subst Kind
ty)