module IR.Constraint.Instantiate (
  fromScheme,
) where

import qualified Common.Identifiers as Ident
import Data.Map.Strict ((!))
import qualified Data.Map.Strict as Map

import qualified IR.Constraint.Canonical as Can
import IR.Constraint.Monad (TC)
import qualified IR.Constraint.Type as Type


-- | FREE VARS
type FreeVars = Map.Map Ident.TVarId Type.Type


-- | FROM SCHEME
fromScheme :: FreeVars -> Can.Type -> TC Type.Type
fromScheme :: FreeVars -> Type -> TC Type
fromScheme FreeVars
freeVars Type
sourceType = case Type
sourceType of
  Can.TCon TConId
tcon [Type]
args -> TConId -> [Type] -> Type
Type.TConN TConId
tcon ([Type] -> Type)
-> StateT TCState (ExceptT Error (WriterT (Doc String) IO)) [Type]
-> TC Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Type -> TC Type)
-> [Type]
-> StateT TCState (ExceptT Error (WriterT (Doc String) IO)) [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (FreeVars -> Type -> TC Type
fromScheme FreeVars
freeVars) [Type]
args
  Can.TVar TVarId
name -> Type -> TC Type
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> TC Type) -> Type -> TC Type
forall a b. (a -> b) -> a -> b
$ FreeVars
freeVars FreeVars -> TVarId -> Type
forall k a. Ord k => Map k a -> k -> a
! TVarId
name