I'm trying to implement flatmap via generics. (Yes, flatmap is already a part of the language.) My attempt uses generic, overloaded functions to accomplish this. (Probably not the most efficient. I know. I've already got a working imperative version.) What I find unexpected is that flatten< T, U >( _ elem: T ) -> [ U ]
is consuming arrays that flatten is called with even though the overload func flatten< T, U >( _ ary: [ T ] ) -> [ U ]
exists.
I can tell what's going wrong, I just can't seem to see why, or even where to look to learn why and possibly fix it.
I've even tried a few casts, just to see, and that produced errors, which made sense to me. Why cast a T
to T
or [ T ]
to [ T ]
?. Also changed ary
to elem
to see if that was causing problems with the overload semantics. Produced the same output.
import Foundation
func flatten< T, U >( _ elem: T ) -> [ U ] {
if let item = elem as? U {
return [ item ]
} else {
return []
}
}
func flatten< T, U >( _ ary: [ T ] ) -> [ U ] {
if ary.count == 0 {
return []
}
return flatten( ary.first ) + flatten( Array( ary.dropFirst() ) )
}
let x: [ Int ] = flatten( [ 1, 2, [ 3, 4 ], [ [ 5, 6 ], nil, 7 ], 8, 9 ] )
print( x ) // Prints [1, 2, 8, 9 ] instead of [1, 2, 3, 4, 5, 6, 7, 8, 9]