Created
March 9, 2019 02:08
-
-
Save DavidGregory084/e5e1eff0117d86100fb5016d6d3655e1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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