diff --git a/src/qir/ast/QIRLambda.java b/src/qir/ast/QIRLambda.java
index 48c9046a5bd7c5056b8a3aea799384063d15a271..33eb76b1c862c88ab96159712c917b28f7a56af9 100644
--- a/src/qir/ast/QIRLambda.java
+++ b/src/qir/ast/QIRLambda.java
@@ -8,8 +8,6 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.source.SourceSection;
 
 import qir.driver.IQIRVisitor;
-import qir.types.QIRAnyType;
-import qir.types.QIRType;
 import qir.util.QIRAny;
 
 /**
@@ -20,7 +18,6 @@ public final class QIRLambda extends QIRNode {
      * The name of the function. {@code null} for an anonymous function.
      */
     private final String funName;
-    private final QIRType type;
     /**
      * A {@link QIRVariable} that represents the argument of the function.
      */
@@ -35,27 +32,18 @@ public final class QIRLambda extends QIRNode {
      */
     private MaterializedFrame env;
 
-    public QIRLambda(final SourceSection source, final String funName, final QIRType type, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) {
+    public QIRLambda(final SourceSection source, final String funName, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) {
         super(source);
         this.funName = funName;
-        this.type = type;
         this.var = var;
         this.body = body;
         this.target = Truffle.getRuntime().createCallTarget(new QIRRootNode(null, var != null ? frameDescr.findOrAddFrameSlot(var.id) : null, body, frameDescr));
     }
 
-    public QIRLambda(final SourceSection source, final String funName, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) {
-        this(source, funName, QIRAnyType.getInstance(), var, body, frameDescr);
-    }
-
     public final String getFunName() {
         return funName;
     }
 
-    public final QIRType getType() {
-        return type;
-    }
-
     public final QIRVariable getVar() {
         return var;
     }
@@ -74,7 +62,7 @@ public final class QIRLambda extends QIRNode {
 
     @Override
     public final String toString() {
-        return (funName != null ? funName : "lambda") + " : " + type.toString() + " " + var + " -> {" + body + "}";
+        return (funName != null ? funName : "lambda") + " " + var + " -> {" + body + "}";
     }
 
     @Override
diff --git a/src/qir/ast/QIRNode.java b/src/qir/ast/QIRNode.java
index edf1bbd8cb874adc2c4d106e3aa6134956ae28aa..2f22c61ab5f65246d8638c5775dec837203d65fb 100644
--- a/src/qir/ast/QIRNode.java
+++ b/src/qir/ast/QIRNode.java
@@ -1,5 +1,8 @@
 package qir.ast;
 
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
 import com.oracle.truffle.api.dsl.ReportPolymorphism;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
@@ -18,6 +21,7 @@ import qir.ast.expression.QIRBoolean;
 import qir.ast.expression.QIRNumber;
 import qir.ast.expression.QIRString;
 import qir.driver.IQIRVisitor;
+import qir.types.QIRType;
 import qir.util.QIRException;
 
 /**
@@ -31,6 +35,7 @@ public abstract class QIRNode extends Node implements InstrumentableNode {
      * The location in the source code of the expression represented by this node.
      */
     protected final SourceSection sourceSection;
+    protected Optional<QIRType> type = Optional.empty();
 
     public QIRNode(final SourceSection sourceSection) {
         this.sourceSection = sourceSection;
@@ -41,6 +46,21 @@ public abstract class QIRNode extends Node implements InstrumentableNode {
         return sourceSection;
     }
 
+    public final Optional<QIRType> getType() {
+        return type;
+    }
+
+    public final QIRType getTypeUnsafe() throws NoSuchElementException {
+        return type.get();
+    }
+
+    public final QIRType setType(final QIRType type) {
+        if (this.type.isPresent())
+            throw new QIRException("Type already set for " + this);
+        this.type = Optional.of(type);
+        return type;
+    }
+
     @Override
     public int hashCode() {
         return super.hashCode();
diff --git a/src/qir/ast/data/QIRList.java b/src/qir/ast/data/QIRList.java
index 2259b5463940f7011b40062741c09b583e7b149f..90c6d9ccdf4ceb368d9d1960f4a93c8fcf5f5cc2 100644
--- a/src/qir/ast/data/QIRList.java
+++ b/src/qir/ast/data/QIRList.java
@@ -10,14 +10,11 @@ import com.oracle.truffle.api.source.SourceSection;
 
 import qir.ast.QIRNode;
 import qir.driver.IQIRVisitor;
-import qir.types.QIRType;
 
 /**
  * {@link QIRList} is the generic representation of a list in QIR.
  */
 public abstract class QIRList extends QIRNode {
-    public QIRType type;
-
     public QIRList(final SourceSection source) {
         super(source);
     }
diff --git a/src/qir/ast/data/QIRRecord.java b/src/qir/ast/data/QIRRecord.java
index 8732c73700ef68fd57d24197631eeb1c305896b9..00da67be72e030b495d78ea45ccfc0759994344d 100644
--- a/src/qir/ast/data/QIRRecord.java
+++ b/src/qir/ast/data/QIRRecord.java
@@ -4,14 +4,11 @@ import com.oracle.truffle.api.source.SourceSection;
 
 import qir.ast.QIRNode;
 import qir.driver.IQIRVisitor;
-import qir.types.QIRType;
 
 /**
  * {@link QIRRecord} is the generic representation of a tuple in QIR.
  */
 public abstract class QIRRecord extends QIRNode {
-    public QIRType type;
-
     public QIRRecord(final SourceSection source) {
         super(source);
     }
diff --git a/src/qir/parser/Parser.java b/src/qir/parser/Parser.java
index 74920a97a7e89b2dddf3cceae1bc708e0b1b0a62..32cf3340dadb36d90950eb25f7067b0bc685da61 100644
--- a/src/qir/parser/Parser.java
+++ b/src/qir/parser/Parser.java
@@ -414,7 +414,7 @@ public class Parser {
 		Expect(21);
 		final Token srcToken = t;
 		Token funName = null;
-		QIRType type = new QIRFunctionType(new QIRType[]{QIRAnyType.getInstance()}, QIRAnyType.getInstance()); 
+		QIRType type = null; 
 		if (la.kind == 22) {
 			Get();
 			Expect(1);
@@ -427,7 +427,10 @@ public class Parser {
 		QIRVariable var = Variable();
 		Expect(24);
 		QIRNode body = QIR();
-		res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, type, var, body, new FrameDescriptor()); 
+		res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, var, body, new FrameDescriptor());
+		if (type != null)
+		res.setType(type);
+		
 		return res;
 	}
 
@@ -450,7 +453,7 @@ public class Parser {
 		res = QIRRnil.getInstance();
 		final Token srcToken = t;
 		Token idToken;
-		QIRType type = QIRAnyType.getInstance(); 
+		QIRType type = null; 
 		if (la.kind == 1) {
 			Get();
 			idToken = t; 
@@ -471,7 +474,8 @@ public class Parser {
 			Get();
 			type = RecordType();
 		}
-		res.type = type; 
+		if (type != null)
+		res.setType(type); 
 		return res;
 	}
 
@@ -479,7 +483,7 @@ public class Parser {
 		QIRList  res;
 		Expect(39);
 		res = QIRLnil.getInstance();
-		QIRType type = QIRAnyType.getInstance();
+		QIRType type = null;
 		final Token srcToken = t; 
 		if (StartOf(1)) {
 			QIRNode value = QIR();
@@ -495,7 +499,8 @@ public class Parser {
 			Get();
 			type = ListType();
 		}
-		res.type = type; 
+		if (type != null)
+		res.setType(type); 
 		return res;
 	}
 
diff --git a/src/qir/parser/qir.atg b/src/qir/parser/qir.atg
index 2934101c9ef59ace663d3a7751d17ee16306a35d..2f2ff195f258fee35df9c14bc2e28f4b9deb32d5 100644
--- a/src/qir/parser/qir.atg
+++ b/src/qir/parser/qir.atg
@@ -153,10 +153,13 @@ identifier																	(. res = new QIRVariable(srcFromToken(t), t.val); .)
 Lambda<out QIRLambda res> =
 "fun"																		(. final Token srcToken = t;
 																			   Token funName = null;
-																			   QIRType type = new QIRFunctionType(new QIRType[]{QIRAnyType.getInstance()}, QIRAnyType.getInstance()); .)
+																			   QIRType type = null; .)
 [ "#" identifier															(. funName = t; .)
 ] [ ":" Type<out type> ] Variable<out QIRVariable var> "->"
-QIR<out QIRNode body>														(. res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, type, var, body, new FrameDescriptor()); .)
+QIR<out QIRNode body>														(. res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, var, body, new FrameDescriptor());
+																			   if (type != null)
+																				 res.setType(type);
+																			.)
 .
 
 Ifexpr<out QIRIf res> =
@@ -169,14 +172,15 @@ Tuplecons<out QIRRecord res> =
 "{"																			(. res = QIRRnil.getInstance();
 																			   final Token srcToken = t;
 																			   Token idToken;
-																			   QIRType type = QIRAnyType.getInstance(); .)
+																			   QIRType type = null; .)
 [
 identifier																	(. idToken = t; .)
 "=" QIR<out QIRNode value>													(. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
 {
 ";" identifier																(. idToken = t; .)
 "=" QIR<out value>															(. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .)
-} ] "}" [ ":" RecordType<out type> ]										(. res.type = type; .)
+} ] "}" [ ":" RecordType<out type> ]										(. if (type != null)
+																				 res.setType(type); .)
 .
 
 Type<out QIRType res> =														(. res = null; .)
@@ -225,13 +229,14 @@ ListType<out QIRListType res> =
 
 Listcons<out QIRList res> =
 "["																			(. res = QIRLnil.getInstance();
-																			   QIRType type = QIRAnyType.getInstance();
+																			   QIRType type = null;
 																			   final Token srcToken = t; .)
 [
 QIR<out QIRNode value>														(. res = new QIRLcons(srcFromToken(srcToken), value, res); .)
 {
 ";" QIR<out value>															(. res = new QIRLcons(srcFromToken(srcToken), value, res); .)
-} ] "]" [ ":" ListType<out type> ]											(. res.type = type; .)
+} ] "]" [ ":" ListType<out type> ]											(. if (type != null)
+																				 res.setType(type); .)
 .
 
 Listdestr<out QIRLdestr res> =
diff --git a/src/qir/typing/QIRGenericTypeSystemVisitor.java b/src/qir/typing/QIRGenericTypeSystemVisitor.java
index f75d067a5893f22e4b3b5cafb879ace0d81f4c6b..b5530e234952ab151832adda810f4697a6bf9472 100644
--- a/src/qir/typing/QIRGenericTypeSystemVisitor.java
+++ b/src/qir/typing/QIRGenericTypeSystemVisitor.java
@@ -64,9 +64,9 @@ public final class QIRGenericTypeSystemVisitor extends QIRTypeSystemVisitor {
     private static final QIRType tryTyping(final QIRNode expr) {
         for (Class<? extends QIRTypeSystemVisitor> specificTypeSystem : specificTypeSystems)
             try {
-                return expr.accept(specificTypeSystem.newInstance());
+                return expr.setType(expr.accept(specificTypeSystem.newInstance()));
             } catch (final QIRTypeErrorException e) {
-            } catch (InstantiationException | IllegalAccessException e) {
+            } catch (final InstantiationException | IllegalAccessException e) {
                 throw new QIRException("Internal error: " + specificTypeSystem.getName() + " could not be instantiated.");
             }
         throw new QIRException("No type system could type " + expr);