 			return .right(.Type(n + 1))
 
 		case let .Variable(i):
-			return environment[i].map(Either.Right) ?? Either.Left("Unexpectedly free variable \(i)")
+			return context[i].map(Either.Right) ?? Either.Left("Unexpectedly free variable \(i)")
 
 		case let .Lambda(i, type, body):
-			return type.typecheck(environment, against: .Type(0))
+			return type.typecheck(context, against: .Type(0))
 				.flatMap { _ in
-					body.typecheck(environment + [ .Local(i): type ])
+					body.typecheck(context + [ .Local(i): type ])
 						.map { Expression.lambda(Recur(type), const(Recur($0))) }
 				}
 
 		case let .Product(a, b):
-			return (a.typecheck(environment) &&& b.typecheck(environment))
+			return (a.typecheck(context) &&& b.typecheck(context))
 				.map { A, B in Expression.lambda(Recur(A), const(Recur(B))) }
 
 		case let .Application(a, b):
-			return a.typecheck(environment)
+			return a.typecheck(context)
 				.flatMap { A in
 					A.analysis(
 						ifLambda: { i, type, body in
-							b.typecheck(environment, against: type.out).map { body.out.substitute(i, $0) }
+							b.typecheck(context, against: type.out).map { body.out.substitute(i, $0) }
 						},
 						otherwise: const(Either.Left("illegal application of \(a) : \(A) to \(b)")))
 				}
 
 		case let .Projection(term, branch):
-			return term.typecheck(environment)
+			return term.typecheck(context)
 				.flatMap { type in
 					type.analysis(
 						ifLambda: { i, A, B in

extension Expression where Recur: FixpointType, Recur: Equatable {
	// MARK: Typechecking

	public func typecheck(environment: [Name: Expression] = [:]) -> Either<Error, Expression> {
		switch destructured {
		case .Unit:
			return .right(.UnitType)

			return .right(.BooleanType)

		case let .If(condition, then, `else`):
			return condition.typecheck(context, against: .BooleanType)
				.flatMap { _ in
					(then.typecheck(context) &&& `else`.typecheck(context))
						.map { a, b in
							a == b
								? a
