Помимо разницы между списком 'A'
и символом ?A
, на который отлично ответил Михаил, в этом коде есть еще один скрытый, но важный глюк.
Вы используете рекурсию, не оптимизированную для хвоста, котораяследует избегать любой ценой.В целом это может привести к переполнению стека.Ниже приведен код TCO.
defmodule RnaTranscription do
def to_rna(dna), do: do_to_rna(dna)
defp do_to_rna(acc \\ [], []), do: Enum.reverse(acc)
defp do_to_rna(acc, [char | tail]),
do: do_to_rna([do_char(char) | acc], tail)
defp do_char(?A), do: ?U
defp do_char(?C), do: ?G
defp do_char(?T), do: ?A
defp do_char(?G), do: ?C
end
RnaTranscription.to_rna('ACTG')
#⇒ 'UGAC'
или, что еще лучше, с пониманием
converter = fn
?A -> ?U
?C -> ?G
?T -> ?A
?G -> ?C
end
for c <- 'ACTG', do: converter.(c)
#⇒ 'UGAC'
Вы можете даже отфильтровать его на месте.
for c when c in 'ACTG' <- 'ACXXTGXX',
do: converter.(c)
#⇒ 'UGAC'