[erlang-questions] Give me some advice
Ulf Wiger
ulf@REDACTED
Sun Feb 11 10:46:34 CET 2007
Den 2007-02-11 06:49:52 skrev LUKE <luke@REDACTED>:
>
> I am tring to do the excise about return a new tuple
> which is a copy of the tuple T where the Nth element
> of the tuple has been replaced by C.
... trying to write an erlang-based version of
the built-in function setelement(N, T, C)?
> Give me some advice on the following poor code. ie.
> tail recursion issue.....
>
> -module(element).
> -export([set2/3]).
>
> set2(N,T,C)->
> list_to_tuple(set2(N,tuple_to_list(T),C,1)).
>
> set2(_,[],_,_)->[];
> set2(N,[H|T],C,Count)->
> if N==Count ->
> [C|set2(N,T,C,Count+1)];
> true->
> [H|set2(N,T,C,Count+1)]
> end.
(1) This is mainly a matter of taste, but
I would order the arguments of set2
differently
(2) When you get to the right position, you
don't have to recurse any further, since
you're guaranteed not to find another match.
set2([_|T], N, N, C) ->
[C|T];
set2([H|T], Pos, N, C) when Pos < N ->
[H|set2(T, Pos+1, N, C)].
(3) You don't need a clause for [], if you add
a guard in set2/3:
set2(N,T,C)
when is_tuple(T),
is_integer(N),
N > 0, N =< size(T) ->
list_to_tuple(set2(tuple_to_list(T),1,N,C)).
(4) It's good form to use guards in the exported
function to clearly indicate what the arguments
are expected to be. Don't worry about this
slowing down your code. It most likely won't,
and in some cases, it can even speed things up,
since the compiler is able to make some
assumptions about the code that follows.
(5) In this case, I wouldn't worry about the
function not being tail-recursive. Doing
it this way makes it a lot easier to break
out of the loop once you've reached N.
Also, your tuple is not likely to have a
huge number of elements to begin with.
BR,
Ulf W
--
Ulf Wiger
More information about the erlang-questions
mailing list