Search code examples
erlangguard

An Erlang guard sequence which checks if a term is a list of length == n


Is it possible to put a guard sequence that would check both term type and its length? I read that the first passing guard makes the whole sequence pass, so I suppose when I check for the term to be a list, it doesn't check the rest guards. Here is the code:

save_key(Key)
    when
      is_list(Key);
      length(Key) == 44 ->

    ok.

Solution

  • In order to combine guard expressions with and, you can separate them with a comma instead of semicolon as mentioned here:

    -module(a).
    -export([save_key/1]).
    
    save_key(Key)
        when
          is_list(Key),
          length(Key) == 44 ->
        ok;
    save_key(_) ->
        ko.
    
    1> c(a).
    {ok,a}
    2> a:save_key([]).
    ko
    3> a:save_key(nil).
    ko
    4> a:save_key(lists:seq(1, 44)).
    ok
    

    Also note that since errors thrown in guards are ignored, you can just add the length(Key) == 44 and get the same behavior as a non-list will throw an error and will not match that clause:

    save_key(Key) when length(Key) == 44 ->
        ok;
    save_key(_) ->
        ko.