 
 
 	public static func lambda(f: DTerm -> (DTerm, DTerm)) -> DTerm {
-		let (type, body) = f(DTerm(DExpression.Variable(-1)))
+		let (type, body) = f(variable(-1, DTerm.kind))
 		let (n, build) = lambdaHelper(DTerm(.Abstraction(-1, Box(type), Box(body))))
-		return build(n + 1)
+		return build(n + 1, type)
 	}
 
-	private static func variable(i: Int) -> DTerm {
-		return DTerm(.Variable(i))
+	private static func variable(i: Int, _ type: DTerm) -> DTerm {
+		return DTerm(.Variable(i, Box(type)))
 	}
 
 	private static func abstraction(i: Int, _ type: DTerm, _ body: DTerm) -> DTerm {
 		return DTerm(.Abstraction(i, Box(type), Box(body)))
 	}
 	
-	private static func lambdaHelper(t: DTerm) -> (Int, Int -> DTerm) {
+	private static func lambdaHelper(t: DTerm) -> (Int, (Int, DTerm) -> DTerm) {
 		return t.expression.analysis(
 			ifKind: const(0, const(t)),
 			ifType: const(0, const(t)),
-			ifVariable: { i in (0, { i == -1 ? self.variable($0) : t }) },
+			ifVariable: { i, _ in (0, { i == -1 ? self.variable($0, $1) : t }) },
 			ifApplication: { a, b in
 				let (ma, builda) = lambdaHelper(a)
 				let (mb, buildb) = lambdaHelper(b)

	public func analysis<T>(
		@noescape #ifKind: () -> T,
		@noescape ifType: () -> T,
		@noescape ifVariable: Int -> T,
		@noescape ifApplication: (Recur, Recur) -> T,
		@noescape ifAbstraction: (Int, Recur, Recur) -> T) -> T {
		switch self {


	case Kind
	case Type
	case Variable(Int, Box<Recur>)
	case Application(Box<Recur>, Box<Recur>)
	case Abstraction(Int, Box<Recur>, Box<Recur>)
}
