[erlang-questions] ** exception error: no function clause matching test_calculate:validate(["1", "+", "1"], []) (test_calculate.erl, line 11)

Richard A. O'Keefe <>
Thu Oct 1 08:41:35 CEST 2015

On 1/10/2015, at 7:15 pm, Roelof Wobben <> wrote:
> One thing is not clear to me. What is the meaning of N. I see that N is equal to zero or to one.

> %% is_number_token(String, N) is true if and only if
> %% String is a list of ASCII decimal digit characters
> %% and N + length(String) > 0.

The comment was supposed to make it tolerably clear.
I hope you *don't* see that, because it isn't true.

Think of the original token as
   Seen_Part ++ Unseen_Part
In is_number_token(String, N),
   String = Unseen_Part
   N = length(Seen_Part)

(Recall that the update was not 1 but N+1.  So N had to be
counting *something*.)

Here's what I might have done in Haskell:

scan :: String -> Maybe [String]
scan cs = if valid_tokens ts then Just ts else Nothing
  where valid_tokens ts = all valid_token ts
        valid_token t = t == "+" || not (null t) && all isDigit t

It's easy to express universal quantification by a loop that
checks each element of a list.  We _almost_ always want a
universal quantification over an empty set to be true; this is
one of the rare cases where we want it to be false and have to
do something special to guard against it.

The counting pattern is useful for identifiers:

is_identifier_token(String) ->
    is_identifier_token(String, 0).

is_identifier_token([], N) ->
    N > 0;
is_identifier_token([C|Cs], N)
  when C =< $9, C >= $0, N > 0 ->
    is_identifier_token(Cs, N+1);
is_identifier_token([C|Cs], N)
  when (C bor 32) >= $a, (C bor 32) =< $z ->
    is_identifier_token(Cs, N+1);
is_identifier_token([$_|Cs], N)
  when N > 0 ->
    is_identifier_token(Cs, N+1);
is_identifier_token(_, _) ->

This allows underscores and digits, but not at the beginning.
And it doesn't allow empty identifiers.

More information about the erlang-questions mailing list