[erlang-questions] The reason for "no case clause matching"error?

Erik Reitsma <>
Thu Jan 3 14:58:21 CET 2008


 
> 2008/1/1, Yoel Jacobsen <>:
> > Hello,
> >
> >
> > I want to implement some sort of list partitioning in Erlang.
> >
> >
> > The ppar function should work like that:
> >
> > ppar [2,2,3] -> [[[2],[2],[3]], [[2],[2,3]], [[2,2],[3]],[ 
> [2,2,3]]] 
> > ppar [2,2,3,4] -> [[[2],[2],[3],[4]], [[2],[2],[3,4]], 
> > [[2],[2,3],[4]], [[2],[2,3,4]], [[2,2],[3],[4]], [[2,2],[3,4]], 
> > [[2,2,3],[4]], [[2,2,3,4]]]
> >
> >
> > This is the code I have written:
> >
> > -module(ppar).
> > -export([ppar/1]).
> >
> >
> > sp(Lhs, []) ->
> >     [[Lhs]];
> > sp(Lhs, Rhs) ->
> >     [lists:append([Lhs], P) || P <- ppar(Rhs)].
> >
> > ppar([]) ->
> >     [[[]]];
> > ppar([H|[]]) ->
> >     [[[H]]];
> > ppar(Lst)  ->
> >     [SP ||
> >     N <- lists:seq(1,length(Lst)),
> >     Lhs = lists:sublist(Lst, 1, N),
> >     Rhs = lists:sublist(Lst, N+1, length(Lst)),
> >     SP <- sp(Lhs, Rhs)].
> >
> > Yet, when I try it I get an error:
> >
> > 1> ppar:ppar([1,2,3]).
> > ** exception error: no case clause matching [1]
> >      in function  ppar:'-ppar/1-lc$^0/1-0-'/2
> >
> > Why is that?
> 
> You cannot use a pattern matching operator inside a list 
> comprehension (or at least, it does not do what you want it 
> to do, it does not give a syntax error, so apparently it 
> means something, though I do not know what). Thus,
> 
> Lhs = lists:sublist(Lst, 1, N),
> 
> is not correct syntax here.

Each qualifier in the comprehension should be a generator or a filter.
The pattern matching operator is neither. See
http://www.erlang.org/doc/reference_manual/expressions.html#6.22

What you could do, probably, is:

ppar(Lst)  ->
     [SP ||
     N <- lists:seq(1,length(Lst)),
     begin
       Lhs = lists:sublist(Lst, 1, N),
       Rhs = lists:sublist(Lst, N+1, length(Lst)),
       true
     end,
     SP <- sp(Lhs, Rhs)].

This way you wrap the matchings into a single expression which returns
true, making it into a stupid filter...

The following shows that you can do matching in a list comprehensions.
Just make sure it evaluates to true or false!

1> [X || X <- [{true,1}, {true,2}, {false,3}], Y=element(1,X)].
[{true,1},{true,2}]

Or worse (using the Y):

2> [{X,Z} || X <- [{true,1}, {true,2}, {false,3}], Y=element(1,X), Z <-
case Y of true -> [1,2]; false -> [3,4] end].
[{{true,1},1},{{true,1},2},{{true,2},1},{{true,2},2}]

Regards,
*Erik.



More information about the erlang-questions mailing list