Prior to antiforms, it was the case that TYPE-BLOCK!s were used, though it attempted to compress by putting the quote levels on the word in the block:
>> type of first [a]
== &[word]
>> type of first ['a]
== &['word]
>> type of first [''a]
== &[''word]
Even that starts to incur performance penalties when you ask for a type. Because it's synthesizing an array on the spot to answer the question--not a huge deal, but it's something. (The only "stock" blocks were the unquoted forms, &[word] etc.)
When quasiforms/antiforms came along, it ran afoul of representation questions. Weird answers like having to do meta forms inside the block:
>> type of first [(a)]
== &['group]
>> type of first [''(a)]
== &['''group]
>> type of spread [a b c]
== &[~group~]
>> type of first [~(a)~]
== &['~group~]
That was rejected as too obfuscating. (Meta forms work all right for things like storing arbitrary values in PACKs, but the above sucks.)
With my performance-blinders on, I don't recall if I ever suggested attacking this via plain words that convey parameterized types as per your Haskell-like suggestion:
>> type of first [(a)]
== &[group]
>> type of first [''(a)]
== &[quoted quoted group]
>> type of spread [a b c]
== &[antiform group] ; or &[splice], if e.g. &[logic] narrows &[antiform word]
>> type of first [~(a)~]
== &[quasi group]
It's tough here though to assume the arity of each type is known, if we imagine this generalizing it might be better to have it structured, where only terminal types aren't in blocks
>> type of first [''(a)]
== &[quoted [quoted group]]
>> type of quote matrix
== &[quoted [matrix 10x10]]
Which adds another performance penalty to grapple with, but it seems important if you're going to say that array destructuring is the method of type destructuring.
If the answer from TYPE OF came back immutable, then magic might be able to compress that behind the scenes. It only would work if it wasn't assumed you could change one reference to the result of TYPE OF and see that in another place.
>> t: type of first ['a]
== &[quoted word]
>> t2: t
== &[quoted word]
>> take t
== quoted
>> t2
== &[word] ; only if cells for t and t2 variables point to common allocation
To point to a common allocation, there has to be an allocation, which subverts some levels of optimization (at least, when one is trying to be competitive with code that does no allocations).
For a similar problem that's been solved, see: PATH! + TUPLE! + CHAIN! compression, explained
I May Like The Parameterized Type Direction
I was already aiming to flip things back so that the &word and &tuple and &path could be used as prettier impromptu type constraints:
parse [1 3 5] [some &odd?]
parse [...] [some &tester?/refinement]
parse [...] [some &obj.tester?]
I think this needs to be done regardless. But if it is done, then switching around to TYPE-BLOCK! for the parameterized types would be available.
The idea of making terminal types equivalent to their predicates might be good or bad. Don't know.
>> group!
== &group?
>> type of first [''(a)]
== &[quoted [quoted &group?]]
Certainly some food for thought here.