18Mar/102
Erlang Programming Exercise: 3-5 (refactor)
I wasn't happy with how the flatten and concatenate functions turned out. They weren't taking advantage of tail call optimizations, so I rewrote the flatten function for fun. During my rewrite I also wanted to avoid using BIFs to work on my pattern matching. I wasn't sure if I would be able to match the head of a list, that was the head of a list. It worked out, here is the result:
flattenHelper(Dst, []) ->
Dst;
flattenHelper(Dst, [[[]|HeadTail]|T]) ->
flattenHelper(Dst, [HeadTail|T]);
flattenHelper(Dst, [[HeadTop|HeadTail]|T]) ->
NewList1 = [HeadTail|T],
NewList2 = [HeadTop|NewList1],
flattenHelper(Dst, NewList2);
flattenHelper(Dst, [[]|T]) ->
flattenHelper(Dst, T);
flattenHelper(Dst, [H|T]) ->
flattenHelper([H|Dst], T);
flattenHelper(Dst, Item) ->
[Item|Dst].
flatten(Lists) ->
reverse(flattenHelper([], Lists)).
Cheers,
-Halzy
November 20th, 2010 - 10:18
Heya-
Found your blog while doing the exercises and searching for the answer to a question I had about 3.5 (writing flatten). Basically it says to use “concatenate to solve flatten” and even though I solved flatten similarly to the first way you did (my code below), I also didn’t use concatenate.
What I’m OCDing on is I actually think his hint on using concatenate is wrong here, because erlang’s lists are untyped (so you never know if your dealing with a list of lists (which is what concatenate takes) until you navigate it).
Regardless, great blog, and I’m going to start following your solutions to his book.
************************
flatten([], Accum) ->
Accum;
flatten([H|[]], Accum) ->
flatten(H, Accum);
flatten([H|T], Accum) ->
flatten(H, flatten(T, Accum));
flatten(Val, Accum) ->
[Val | Accum].
flatten(List) ->
flatten(List,[]).
February 13th, 2011 - 13:31
With restriction of using concatenate very similar function can be written:
flatten2(List) -> reverse( flatten_helper(List,[]) ).
flatten_helper([],Dst) -> Dst;
flatten_helper([H|T],Dst) when is_list(H) -> flatten_helper( concatenate([H,T]), Dst );
flatten_helper([H|T],Dst) -> flatten_helper( T, [H|Dst] ).
you could avoid is_list by matching [[HH|HT]|T] and [[]|T] separately as in your example.
I am now trying to break it