diff --git a/lib/DhallishGrammar.treetop b/lib/DhallishGrammar.treetop
index f6e9c9bb99118b754d0c8e6f87e2f102171d6252..703588a01b816e47ff7a511122fc222d2252a243 100644
--- a/lib/DhallishGrammar.treetop
+++ b/lib/DhallishGrammar.treetop
@@ -167,12 +167,8 @@ grammar DhallishGrammar
 	end
 
 	## Union Literals
-	rule union_literal_one_member
-		"<" space? label space? "=" space? expression ">"
-	end
-
 	rule union_literal
-		"<" space? start:(lb:label space? ":" space? type:expression space? "|" space?)* lb:label space? "=" space? expr:expression tail:(space? "|" space? lb:label space? ":" space? type:expression)* space? ">"
+		"<" space? start:(lb:label space? ":" space? type:record_merge_expression space? "|" space?)* lb:label space? "=" space? expr:record_merge_expression tail:(space? "|" space? lb:label space? ":" space? type:record_merge_expression)* space? ">"
 		{
 			def to_node(ctx)
 				typed_labels = {}
@@ -193,7 +189,7 @@ grammar DhallishGrammar
 
 	rule union_type_literal
 		empty_union_type_literal { def to_node(ctx) Dhallish::Ast::UnionType.new({})  end } /
-		"<" space? lb:label space? ":" space? type:expression tail:(space? "|" space? lb:label space? ":" space? type:expression)* space? ">"
+		"<" space? lb:label space? ":" space? type:record_merge_expression tail:(space? "|" space? lb:label space? ":" space? type:record_merge_expression)* space? ">"
 		{
 			def to_node(ctx)
 				type_map = {lb.text_value => type.to_node(ctx)}
@@ -388,7 +384,7 @@ grammar DhallishGrammar
 			def to_node(ctx)
 				tail.elements.reduce(pe.to_node(ctx)) { |tree, node|
 					if node.sel.respond_to? :a
-						Dhallish::Ast::RecordSelector.new tree, node.sel.a.text_value
+						Dhallish::Ast::RecordUnionSelector.new tree, node.sel.a.text_value
 					else
 						Dhallish::Ast::RecordProjection.new tree, node.sel.b.to_list()
 					end
diff --git a/lib/ast.rb b/lib/ast.rb
index d45d57cb86845a29f807e07107834daca2d333df..1e1a59ba4b919f691c86407be96a1c4d861511be 100644
--- a/lib/ast.rb
+++ b/lib/ast.rb
@@ -422,7 +422,7 @@ module Dhallish
 		end
 
 		# rec: ast node of something that will be a record, key: name of key to access in record (string)
-		class RecordSelector
+		class RecordUnionSelector
 			attr_accessor :rec
 			attr_accessor :key
 			def initialize(rec, key)
@@ -432,13 +432,29 @@ module Dhallish
 
 			def compute_type(ctx)
 				rectype = @rec.compute_type ctx
-				assert("`.` can only be used on records, the key `#{@key}` must exist") { rectype.is_a? Types::Record and !rectype.types[@key].nil? }
-				rectype.types[@key]
+				assert("`.` can only be used on records and unions, the key `#{@key}` must exist") { 
+					((rectype.is_a? Types::Record or rectype.is_a? Types::Union) and !rectype.types[@key].nil?) \
+					or (rectype.is_a? Types::Type and rectype.metadata.is_a? Types::Union)
+				}
+				if rectype.is_a? Types::Union	
+					Types::Optional.new rectype.types[@key]
+				elsif rectype.is_a? Types::Record
+					rectype.types[@key]
+				else
+					union_type = rectype.metadata
+					Types::Function.new union_type.types[@key], union_type
+				end
 			end
 
 			def evaluate(ctx)
 				rec = @rec.evaluate ctx
-				rec[@key]
+				if rec.is_a? Union
+					rec.select @key
+				elsif rec.is_a? Hash  # <== Record
+					rec[@key]
+				else
+					BuiltinFunction.new { |val| Union.new @key, val, rec }
+				end
 			end
 		end
 
@@ -662,6 +678,8 @@ module Dhallish
 			attr_accessor :map
 			attr_accessor :init_label
 			attr_accessor :init_val
+			attr_accessor :type
+
 			def initialize(map, init_label, init_val)
 				@map = map
 				@init_label = init_label
@@ -670,18 +688,21 @@ module Dhallish
 
 			def compute_type(ctx)
 				types = {}
-				@map.each { |key, node|
+				@map.keys.each { |key|
+					node = @map[key]
 					assert ("duplicate labels not allowed in union literals") { !types.include? key }
-					types[key] = node.compute_type(ctx)
+					type_type = node.compute_type(ctx)
+					assert ("Type annotation in Union Literal not a type") { type_type.is_a? Types::Type }
+					@map[key] = types[key] = type_type.metadata
 				}
 				assert ("duplicate labels not allowed in union literals") { !types.include? @init_label }
 				types[@init_label] = @init_val.compute_type(ctx)
-				Types::Union.new(types)
+				@type = Types::Union.new(types)
+				@type
 			end
 
 			def evaluate(ctx)
-				res = {@init_label => @init_val.evaluate(ctx)}
-				res
+				Union.new @init_label, @init_val, @type
 			end
 		end