I have recently started to study Erlang and have encountered a curious exception which I cannot explain.
My source code is as follows:
-module(balanced_brackets).
-author("Irrelevant").
-compile(export_all).
is_balanced(String) -> is_balanced(String, 0, 0).
is_balanced([H | T], Opening, Closing) when H =:= "{" ->
is_balanced(T, Opening + 1, Closing);
is_balanced([H | T], Opening, Closing) when H =:= "}" ->
is_balanced(T, Opening, Closing + 1);
is_balanced([], Opening, Closing) -> (Opening - Closing).
Very basic code to count the number of closing and opening curly brackets in a string.
In the Erlang shell, when I try to call the function is_balanced as such:
balanced_brackets:is_balanced("{}").
The following error is output:
** exception error: no function clause matching balanced_brackets:is_balanced("{}",0,0) (balanced_brackets.erl, line 7)
However, if I pass the argument as an explicit list, pattern matching works correctly:
balanced_brackets:is_balanced(["{", "}"]).
Aren't Erlang strings simply lists internally? Why is it incorrect to pattern match a string using the construct [H | T]
?
Executing the BIF is_list("{}").
returns true
.
I would sincerely appreciate somebody's explanation for the exception.
Thank you.
Erlang/OTP 17 [erts-6.2] [source-aaaefb3] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]
The problem is your guard definition, you are comparing to "{"
which is [123]
, i.e. a list with one element representing {
.
Your pattern matching is correct, but you will want to match against 123
instead of "{"
(and the same for }
of course).
The easiest way to fix your code (and keep it readable) is to compare to [H]
instead of H
in the guards:
is_balanced([H | T], Opening, Closing) when [H] =:= "{" ->
is_balanced(T, Opening + 1, Closing);