String handling

Home Forums Basic Erlang String handling

This topic contains 3 replies, has 3 voices, and was last updated by  Joseph 4 months, 3 weeks ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
  • #67648

    The to_rna/1 function below fails for multi-character inputs (the last pattern). For example, it should convert input “AC” to “UG”.

    to_rna(N) when N == "G" -> "C";
    to_rna(N) when N == "C" -> "G";
    to_rna(N) when N == "T" -> "A";
    to_rna(N) when N == "A" -> "U";
    to_rna([N|T]) ->
        % Given to_rna("AC"), keep N as "A"?
        N1 = io:format("~c", [N]), % 65 -> "Aok"
        N2 = string:substr(N1,1,1), % "Aok" -> "A"
        %% [to_rna(N2)] ++ to_rna(T).

    Command-line erl gives this error:

    1> c(rna_transcription).
    rna_transcription.erl:8: Warning: variable 'T' is unused
    2> rna_transcription:to_rna("AC").
    A** exception error: no function clause matching string:substr2(ok,1) (string.erl, line 213)
         in function  string:substr/3 (string.erl, line 208)

    PS. How can erl be made more user-friendly? E.g., how can history ignore duplicates similar to Bash’s HISTCONTROL=ignoredups:erasedups, how can history be saved between session, how can prompt be colored, how can one make custom keybindings (say for deleting a word backwards in place of the default C-w), etc.?


    Using io_lib instead of io “solved” the problem. Here’s the corrected last pattern match:

    to_rna([N|T]) ->
        N1 = io_lib:format("~c", [N]),
        N2 = lists:nth(1, N1),
        lists:flatten([to_rna(N2), to_rna(T)]).

    Please point out if there’s a better, more idiomatic and/or performant solution.


    Unfortunately, I did not understand exactly what you need. But I’d rewrite the function as follows:

    to_rna(List) -> string:join(lists:map(fun(X)->
    case string:chr("GCTA",X) of
    	1 -> "C";
    	2 -> "G";
    	3 -> "A";
    	4 -> "U"
    end end,List),"").

    1. When will your procedure bottom out? The very last thing it’ll see is the [], i.e. when it reaches the end of string (which is just a list of characters).
    2. An io:format/2 will write to standard output and return an ok: see The Erlang shell prints the return value too, which is why you get an ok following the character that got printed. To see this try: Result = io:format("~p", ["bar"]). then Result. in the shell.

    See this Gist:

    1. Pattern matching in the procedure head rather than the guard.
    2. List comprehensions are idiomatic: what it does is clear
    3. Procedures aren’t overloaded, in any way, they keep to one type: character and list. That’s helpful if you use the Erlang type analyser.
    • This reply was modified 4 months, 3 weeks ago by  Joseph.
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.