Class: Typisch::Type::Constructor

Inherits:
Typisch::Type show all
Defined in:
lib/typisch/constructor.rb

Overview

All types except Top, Bottom and Unions (which may necessarily involve more than one constructor type) have a tag associated with them which is used at runtime to distinguish its instances somewhat from instances of other types.

This is an abstract superclass; each subclass of Type::Constructor is assumed to implement its own, distinct lattice of types. For simple atomic types like Bool, there will only be one tag, “Bool”, in that lattice.

While the type lattices of different subclass of Type::Constructor are non-overlapping, within a subclass (such as Type::Object or Type::Numeric) there may be a non-trivial type lattice, eg for Numeric, Int < Float, and for Object, the type lattice is based on a nominal tag inheritance hierarchy in the host language together with structural subtyping rules for object properties.

A list of ‘reserved tags’ is maintained globally, and any Type::Constructor subtype which allows custom user-specified tags to be used should ensure that they don’t match any reserved tags.

Direct Known Subclasses

Singleton, Numeric, Object, Sequence, String, Tuple

Defined Under Namespace

Classes: Singleton

Constant Summary collapse

CONSTRUCTOR_TYPE_SUBCLASSES =
[]

Instance Attribute Summary

Attributes inherited from Typisch::Type

#name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Typisch::Type

#<, #<=, #<=>, #==, #===, #>, #>=, #annotations, #annotations=, #canonicalize!, #excluding_null, #inspect, #recursive?, #shallow_check_type, #subexpression_types, subtype?, #target, #to_s, #to_string

Class Method Details

.check_subtype(x, y, &recursively_check_subtype) ⇒ Object

This gets called by the subtyper on a Type::Constructor subclass, with two instances of that subclass. It should return true or false; if it needs to check some subgoals, say on child types of the ones passed in, it should use the supplied ‘recursively_check_subtype’ block rather than calling itself recursively directly. This hides away the details of the corecursive subtyping algorithm for you.

Raises:

  • (NotImplementedError)


46
47
48
# File 'lib/typisch/constructor.rb', line 46

def check_subtype(x, y, &recursively_check_subtype)
  raise NotImplementedError
end

.inherited(subclass) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/typisch/constructor.rb', line 20

def inherited(subclass)
  # we add any non-abstract subclasses to this list, which is used to
  # construct the Any type. For now Constructor::Singleton is the only
  # other abstract Type::Constructor subclass:
  unless subclass == Type::Constructor::Singleton
    CONSTRUCTOR_TYPE_SUBCLASSES << subclass
  end
  super
end

.top_type(overall_top) ⇒ Object

This should be the top in the type lattice for this class of taged types. Its tag should be the top_tag above. You are passed the overall_top, ie the top type of the overall type lattice, to use; this is needed by parameterised types which want to parameterise their top type by the overall top, eg Top = Foo | Bar | Sequence | …

Raises:

  • (NotImplementedError)


35
36
37
# File 'lib/typisch/constructor.rb', line 35

def top_type(overall_top)
  raise NotImplementedError
end

Instance Method Details

#alternative_typesObject

these are here so as to implement a common interface with Type::Union



71
72
73
# File 'lib/typisch/constructor.rb', line 71

def alternative_types
  [self]
end

#check_type(instance) ⇒ Object



61
62
63
# File 'lib/typisch/constructor.rb', line 61

def check_type(instance)
  shallow_check_type(instance)
end

#tagObject

the tag of this particular type

Raises:

  • (NotImplementedError)


66
67
68
# File 'lib/typisch/constructor.rb', line 66

def tag
  raise NotImplementedError
end

#type_latticeObject

the distinct type lattice within which this type lives. the type system as a whole can be seen as a set of non-overlapping type lattices, together with tagged unions drawn from them.

the interface for a type lattice is just that it responds to ‘check_subtype’; by default the class of a type implements this interface



57
58
59
# File 'lib/typisch/constructor.rb', line 57

def type_lattice
  self.class
end