~singpolyma/dhall-ruby

2b29af325093994cc48a6b3f6b63b04dfb5254f4 — Stephen Paul Weber 3 years ago 6c70ab5
List stores full type, allows for unusual annotation
3 files changed, 42 insertions(+), 13 deletions(-)

M lib/dhall/ast.rb
M lib/dhall/binary.rb
M lib/dhall/normalize.rb
M lib/dhall/ast.rb => lib/dhall/ast.rb +32 -9
@@ 373,9 373,18 @@ module Dhall

		include(ValueSemantics.for_attributes do
			elements     Util::ArrayOf.new(Expression, min: 1)
			element_type Either(nil, Expression), default: nil
			type         Either(nil, Expression), default: nil
		end)

		def initialize(attrs)
			if attrs.key?(:element_type)
				et = attrs.delete(:element_type)
				attrs[:type] = self.class.as_dhall.call(et) if et
			end

			super
		end

		def self.of(*args, type: nil)
			if args.empty?
				EmptyList.new(element_type: type)


@@ 388,11 397,13 @@ module Dhall
			Builtins[:List]
		end

		def type
			Dhall::Application.new(
				function: self.class.as_dhall,
				argument: element_type
			)
		def element_type
			if type.nil?
			elsif type.is_a?(Application) && type.function == Builtins[:List]
				type.argument
			else
				raise "Cannot get element_type of: #{type.inspect}"
			end
		end

		def as_json


@@ 400,9 411,10 @@ module Dhall
		end

		def map(type: nil, &block)
			type = type.nil? ? nil : Builtins[:List].call(type.as_dhall)
			with(
				elements:     elements.each_with_index.map(&block),
				element_type: type&.as_dhall
				elements: elements.each_with_index.map(&block),
				type:     type
			)
		end



@@ 450,11 462,22 @@ module Dhall

	class EmptyList < List
		include(ValueSemantics.for_attributes do
			element_type Either(nil, Expression)
			type Either(nil, Expression)
		end)

		def initialize(attrs)
			if attrs.key?(:element_type)
				et = attrs.delete(:element_type)
				attrs[:type] = self.class.as_dhall.call(et) if et
			end

			super
		end

		def as_json
			[4, element_type.as_json]
		rescue
			[28, type.as_json]
		end

		def map(type: nil)

M lib/dhall/binary.rb => lib/dhall/binary.rb +9 -3
@@ 85,15 85,21 @@ module Dhall

	class List
		def self.decode(type, *els)
			type = type.nil? ? nil : Dhall.decode(type)
			type = type.nil? ? nil : Builtins[:List].call(Dhall.decode(type))
			if els.empty?
				EmptyList.new(element_type: type)
				EmptyList.new(type: type)
			else
				List.new(elements: els.map(&Dhall.method(:decode)), element_type: type)
				List.new(elements: els.map(&Dhall.method(:decode)), type: type)
			end
		end
	end

	class EmptyList
		def self.decode(type)
			EmptyList.new(type: Dhall.decode(type))
		end
	end

	class Optional
		def self.decode(type, value=nil)
			if value.nil?

M lib/dhall/normalize.rb => lib/dhall/normalize.rb +1 -1
@@ 245,7 245,7 @@ module Dhall

	class EmptyList
		def normalize
			super.with(element_type: element_type.normalize)
			super.with(type: type.normalize)
		end
	end