[erlang-questions] Wildcard matching a list of strings vs atoms/binaries

Richard Carlsson carlsson.richard@REDACTED
Wed Apr 17 23:40:53 CEST 2013


On 2013-04-17 22:26, Olav Frengstad wrote:
> Hey,
>
> I'm getting some unexpected behavior when trying to pattern match the
> head of a list.
>
> When matching against a list of integers I can successfully do a
> wildcard match:
> 27> ("ab ++ _)  = "abcd".
>
> But when trying to do the same with a list of atoms i get the error: *
> 1: illegal pattern:
> 28>  ([a,b,c] ++ _) = [a,b,c,d].
> * 1: illegal pattern
>
> So just making sure there's no magic in string matching i also try with
> an actual list of integers:
> 29> ([0,1,2] ++ _) = [0,1,2,3,4].
> [0,1,2,3,4]
>
> Why can't I pattern match a lists with other values integers?

The Erlang Reference Manual 
(http://www.erlang.org/doc/reference_manual/expressions.html#id76648) 
says the following:

   When matching strings, the following is a valid pattern:

     f("prefix" ++ Str) -> ...

   This is syntactic sugar for the equivalent, but harder to read

     f([$p,$r,$e,$f,$i,$x | Str]) -> ...

Since strings are really just lists of integers, and the double-quoted 
string syntax has been expanded to actual lists by the time the compiler 
gets the code, it actually works on lists of any integers, as in your 
example:

   ([0,1,2] ++ _) = [0,1,2,3,4].

There's no particular reason that this syntax couldn't be allowed for 
lists of arbitrary elements, but apparently, that hasn't been done. In 
fact, it seems that the compiler (in the module sys_pre_expand) doesn't 
care about what the elements are, but the erl_lint module that checks 
the code after parsing explicitly disallows this syntax for other things 
than strings/lists of integers.

For now, you'll just have to use the normal list pattern syntax for 
matching prefixes:

    [a,b,c | _] = [a,b,c,d].

In any case, the (Prefix++Tail) pattern can only be used when Prefix is 
a fixed-length list literal (so it can be rewritten to the last form at 
compile time). Prefix can never be a variable.

     /Richard




More information about the erlang-questions mailing list