; P07 Flatten a nested array structure. ; Transform an array, possibly holding arrays as elements into a `flat' ; list by replacing each array with its elements (recursively). (def a (list "a" (list "b" (list "c" "d") "e"))) ; this belongs in stdlib (func extend (lst1 lst2) (reduce append lst2 lst1)) ; can overload functions of different arities (func flatten-iter (item) (flatten-iter item (list))) ; iterative solution (func flatten-iter (item acc) (branch ((eq? (typeof item) :[:any]) (if (empty? item) acc (flatten-iter (rest item) (extend acc (flatten-iter (first item)))))) (#true (append acc item)))) ; we can also use the type system/dynamic dispatch to split up the work (func flatten-typ (item) (flatten-typ item (list))) ; non-empty lists (func flatten-typ (lst :{:any} acc) (flatten-typ (rest lst) (extend acc (flatten-typ (first lst))))) ; empty lists (func flatten-typ (lst :nil acc) acc) ; other things ; note: we would need to know what type(s) is inside the list to avoid an ; ambiguous definition ;(func flatten-typ (item :string acc) ; (append acc item)) ; this might be clearer/more flexible ; maybe "not this type" should be a thing, like :![:any] (func not-a-list? (item) (not (eq? (typeof item) :[:any]))) (type :not-a-list :any not-a-list?) ; should be able to pass a lambda ; this handles anything that's not a list (func flatten-typ (item :not-a-list acc) (append acc item)) (print (->string a)) (print (->string (flatten-iter a))) (print (->string a)) (print (->string (flatten-typ a)))