Skip to content

Instantly share code, notes, and snippets.

@DavidGregory084
Created March 9, 2019 02:08
Show Gist options
  • Save DavidGregory084/e5e1eff0117d86100fb5016d6d3655e1 to your computer and use it in GitHub Desktop.
Save DavidGregory084/e5e1eff0117d86100fb5016d6d3655e1 to your computer and use it in GitHub Desktop.
diff --git a/typechecker/src/inc/typechecker/Gather.scala b/typechecker/src/inc/typechecker/Gather.scala
index 4288483..e472854 100644
--- a/typechecker/src/inc/typechecker/Gather.scala
+++ b/typechecker/src/inc/typechecker/Gather.scala
@@ -46,6 +46,11 @@ class Gather(isTraceEnabled: Boolean) {
}
}
+ def substitute(env: Environment, subst: Substitution): Environment = {
+ if (subst.nonEmpty) scribe.trace(NL + "Apply substitution: " + Printer.print(subst))
+ env.mapValues(_.substitute(subst))
+ }
+
def withTypeScheme(expr: Expr[NameWithPos], typ: TypeScheme): Infer[(Expr[NamePosType], List[Constraint])] = {
val exprWithType = expr.map(_.withType(typ))
Right((exprWithType, List.empty))
@@ -214,24 +219,35 @@ class Gather(isTraceEnabled: Boolean) {
decl: TopLevelDeclaration[NameWithPos],
env: Environment,
source: String
- ): Infer[(TopLevelDeclaration[NamePosType], List[Constraint])] =
+ ): Infer[(TopLevelDeclaration[NamePosType], List[Constraint])] = {
+ val solve = new Solve(isTraceEnabled)
+
decl match {
case let @ Let(name, expr, meta) =>
gather(expr, env, source).flatMap {
case (checkedExpr, constraints) =>
- val eTp = checkedExpr.meta.typ.typ
- val tp = TypeScheme.generalize(env, eTp)
+ val exprTp = checkedExpr.meta.typ.typ
- if (tp.bound.nonEmpty)
- scribe.trace(NL + "Generalize: " + tp.bound.map(Printer.print(_)).mkString("[", ", ", "]"))
+ trace(name, meta.pos, exprTp, source)
- trace(name, meta.pos, tp, source)
+ solve.solve(constraints).map { subst =>
+ val updatedEnv = substitute(env, subst)
+ val updatedTp = exprTp.substitute(subst)
+ val tp = TypeScheme.generalize(updatedEnv, updatedTp)
- val checkedLet = let.copy(binding = checkedExpr, meta = meta.withType(tp))
+ val checkedLet = let.copy(
+ binding = checkedExpr,
+ meta = meta.withType(tp)
+ )
- Right((checkedLet, constraints))
+ if (tp.bound.nonEmpty)
+ scribe.trace(NL + "Generalize: " + tp.bound.map(Printer.print(_)).mkString("[", ", ", "]"))
+
+ (checkedLet, constraints)
+ }
}
}
+ }
def gather(
module: Module[NameWithPos],
diff --git a/typechecker/src/inc/typechecker/Solve.scala b/typechecker/src/inc/typechecker/Solve.scala
index 3696d7d..5b72912 100644
--- a/typechecker/src/inc/typechecker/Solve.scala
+++ b/typechecker/src/inc/typechecker/Solve.scala
@@ -18,7 +18,6 @@ class Solve(isTraceEnabled: Boolean) {
).replace()
}
- type Substitution = Map[TypeVariable, Type]
val EmptySubst: Substitution = Map.empty
def chainSubstitutions(ss: List[Substitution]): Substitution =
diff --git a/typechecker/src/inc/typechecker/package.scala b/typechecker/src/inc/typechecker/package.scala
index 6f268e0..4941d36 100644
--- a/typechecker/src/inc/typechecker/package.scala
+++ b/typechecker/src/inc/typechecker/package.scala
@@ -9,4 +9,5 @@ import scala.collection.immutable.{ List, Map }
package object typechecker {
type Infer[A] = Either[List[TypeError], A]
type Environment = Map[String, TypeScheme]
+ type Substitution = Map[TypeVariable, Type]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment