I've now also modified the soft cast operator to do more what people expect. It's almost working for map():
typeof(map);
(1) Result: function(array((1=mixed)), function(1, (0=zero) ... : (2=void | mixed)), 0 ... : array(2)) | !function(!array((1=mixed)), function, !zero ... : mixed) & (function(array((1=mixed)), program, mixed ... : array(object)) | function(array((1=mixed)), object, mixed ... : array)) | function(array((1=mixed)), multiset, mixed ... : array(int(0..1))) | function(array((1=mixed)), mapping(mixed:(2=mixed)), mixed ... : array(int(0..0) | 2)) | function(array((1=mixed)), array, mixed ... : array(array)) | function(array((1=mixed)), int(0..0), mixed ... : array) | function(array((1=mixed)) : array) | function(mapping((3=mixed):(1=mixed)), function(1, (0=zero) ... : (2=void | mixed)), 0 ... : mapping(3:2)) | !function(!mapping((3=mixed):(1=mixed)), function, !zero ... : mixed) & (function(mapping((3=mixed):(1=mixed)), program, mixed ... : mapping(3:object)) | function(mapping((3=mixed):(1=mixed)), object, mixed ... : mapping(3:mixed))) | function(mapping((3=mixed):(1=mixed)), mult iset, mixed ... : mapping(3:int(0..1))) | function(mapping((3=mixed):(1=mixed)), mapping(mixed:(2=mixed)), mixed ... : mapping(3:int(0..0) | 2)) | function(mapping((3=mixed):(1=mixed)), array, mixed ... : mapping(3:array)) | function(mapping((3=mixed):(1=mixed)), int(0..0), mixed ... : mapping(3:mixed)) | function(mapping((3=mixed):(1=mixed)) : mapping(3:mixed)) | function(multiset((1=mixed)), function(1, (0=zero) ... : (2=void | mixed)), 0 ... : multiset(2)) | !function(!multiset((1=mixed)), function, !zero ... : mixed) & (function(multiset((1=mixed)), program, mixed ... : multiset(object)) | function(multiset((1=mixed)), object, mixed ... : multiset)) | function(multiset((1=mixed)), multiset, mixed ... : multiset(int(0..1))) | function(multiset((1=mixed)), mapping(mixed:(2=mixed)), mixed ... : multiset(int(0..0) | 2)) | function(multiset((1=mixed)), array, mixed ... : multiset(array)) | function(multiset((1=mixed)), int(0..0), mixed ... : multiset) | function(multiset((1=m ixed)) : multiset) | function(program | function, function(mixed, (0=zero) ... : (2=void | mixed)), 0 ... : mapping(string:2)) | !function(!(program | function), function, !zero ... : mixed) & (function(program | function, program, mixed ... : mapping(string:object)) | function(program | function, object, mixed ... : mapping(string:mixed))) | function(program | function, multiset, mixed ... : mapping(string:int(0..1))) | function(program | function, mapping(mixed:(2=mixed)), mixed ... : mapping(string:int(0..0) | 2)) | function(program | function, array, mixed ... : mapping(string:array)) | function(program | function, int(0..0), mixed ... : mapping(string:mixed)) | function(program | function : mapping(string:mixed)) | function(string, function(int, mixed ... : int), mixed ... : string) | function(string, function(int, mixed ... : int), mixed ... : string) | function(string, multiset, mixed ... : string) | function(string, mapping(mixed:int), mixed ... : string) | function( array(mapping | object | function | program | multiset), string, mixed ... : array) | function(mapping((3=mixed):mapping | object | function | program | multiset), string, mixed ... : mapping(3:mixed)) | function(multiset(mapping | object | function | program | multiset), string, mixed ... : multiset) | function(program | function, string, mixed ... : mapping) | function(object, mixed ... : mixed)
constant zero = typeof(0); typeof([function(array,zero...:mixed)]map);
(2) Result: function(array, string, mixed ... : array) | void | function(array, multiset, mixed ... : array(int(0..1))) | function(array, array, mixed ... : array(array)) | function(array, zero ... : array) | function(array, int(0..0), mixed ... : array) | function(array, mapping(mixed:(2=mixed)), mixed ... : array(int(0..0) | 2)) | function(array, function(1, (0=zero) ... : (2=void | mixed)), 0 ... : array(2))