def flatten_type(object)
if object.is_a?(Array)
flatten_type(object[0])
else
object
end
end
x = [1, [2, ['a', 'b']]]
puts x[0].is_a? Array # => false
puts typeof(x[0]) # => (Array(Array(Char) | Int32) | Int32)
puts typeof(flatten_type([1, [2, ['a', 'b']]])) # => Int32 | Char
I can’t understand how flatten_type can flatten the nested type.
x = [1, [2, [‘a’, ‘b’]]]; the object[0] is x[0], it is 1, right? the type of 1 is (Array(Array(Char) | Int32) | Int32), how it change to Int32 | Char ?
This is the part that’s actually slightly different.
The compiler doesn’t know what’s in the first position of the array. You know x[0] is an int, but for the compiler that could be an int or the other array.
It’s easier if you also print the types as the compiler figures things out:
def flatten_type(object : T) forall T
{% puts "typeof(object) is #{T}" %}
if object.is_a?(Array)
show_typeof_object0(object[0])
flatten_type(object[0])
else
show_typeof_object(object)
object
end
end
def show_typeof_object0(x : T) forall T
{% puts "typeof(object[0]) is #{T}" %}
end
def show_typeof_object(x : T) forall T
{% puts "typeof(object) is #{T}" %}
end
flatten_type([1, [2, ['a', 'b']]])
The output is:
typeof(object) is Array(Array(Array(Char) | Int32) | Int32)
typeof(object[0]) is (Array(Array(Char) | Int32) | Int32)
typeof(object) is (Array(Array(Char) | Int32) | Int32)
typeof(object[0]) is (Array(Char) | Int32)
typeof(object) is (Array(Char) | Int32)
typeof(object[0]) is Char
typeof(object) is Char
typeof(object) is Char
typeof(object) is Int32
Another way to understand this:
a = [1, 'a']
puts typeof(a[0]) # => Char | Int32
That is, typeof(a[0]) is not Int32, it’s the union. The compiler can’t know (in general) what’s in each position of the array.