This code compiles successfully.
class Item(V)
def initialize(@value : V, @name : String? = nil )
end
end
class Queue(V) < Array(Item(V))
def unshift(value : V, name = nil)
item = Item(V).new(value, name)
unshift(item)
end
end
queue = Queue(Array(String)).new
queue.unshift ["S"]
queue = Queue(Tuple(String)).new
queue.unshift({"S"})
queue = Queue(Array(Array(String))).new
queue.unshift([["S"]])
queue = Queue(Array(Array(Array(String)))).new
queue.unshift([[["S"]]])
queue = Queue(Array(Tuple(String))).new
queue.unshift([{"S"}])
But when the type V is Tuple(Array(String)), it throws a meaningless error.
queue = Queue(Tuple(Array(String))).new
queue.unshift({["S"]})
gshah@workstation expt]$ crystal run src/expt.cr
Showing last frame. Use --error-trace for full trace.In /usr/lib/crystal/array.cr:1933:21
1933 | @buffer.value = object
^-----
Error: type must be Item(Tuple(Array(String))), not Item(Tuple(Array(String)))
This error can be mitigated if we explicitly specify the type. With this, the code compiles successfully.
queue.unshift({["S"]}.as(Tuple(Array(String))))
Why is explicit type specification needed for Tuple(Array(String))) but not for other complex types?