When working with lists a all elements are often of similar datatype or meaning. You seldom see lists like ["John Doe","1970-01-01","London"]
but rather #person{name="John Doe",...}
or even {"John Doe",...}. To change a value in a record and tuple:
-record(person,{name,born,city}).
f(#person{}=P) -> P#person{city="New City"}. % record
f({_,_,_,}=Tuple) -> erlang:setelement(3,Tuple,"New City"). % tuple
This might not solve anything for your particular problem. To take your own example in comment:
f1([H1,H2,_H3,H4,H5],E) -> [H1,H2,E,H4,H5].
If you give a more specific description of the environment and problem it's easier to under which solution might work the best.
Edit: One (rather bad) solution 1.
replacenth(L,Index,NewValue) ->
{L1,[_|L2]} = lists:split(Index-1,L),
L1++[NewValue|L2].
1> replacenth([1,2,3,4,5],3,foo).
[1,2,foo,4,5]
Or slightly more efficient depending on the length of your lists.
replacenth(Index,Value,List) ->
replacenth(Index-1,Value,List,[],0).
replacenth(ReplaceIndex,Value,[_|List],Acc,ReplaceIndex) ->
lists:reverse(Acc)++[Value|List];
replacenth(ReplaceIndex,Value,[V|List],Acc,Index) ->
replacenth(ReplaceIndex,Value,List,[V|Acc],Index+1).
Even better is my function f1 above but maybe, just maybe the problem is still located as discussed above or here.