[erlang-questions] array search problem
Richard A. O'Keefe
ok@REDACTED
Mon Feb 2 01:40:36 CET 2015
On 31/01/2015, at 5:36 am, Roelof Wobben <r.wobben@REDACTED> wrote:
> Hello,
>
> Im still struggeling to make the database exercise working.
>
> I have to implement a read method which outputs as this :
>
> 5> db:read(francesco, Db2).
> {ok,london}
> 6> Db3 = db:write(joern, stockholm, Db2).
> [{joern,stockholm},{lelle,stockholm},{francesco,london}]
> 7> db:read(ola, Db3).
> {error,instance}
>
> To achieve this do I need to use a try catch or can I achieve this with only pattern matching.
What on earth would you use a try-catch *for*?
Your so-called "data base" is a thing that has been known as an
"association list" at least since the "Lisp 1.5 programmer's manual"
came out in 1962.
Think about a CASE ANALYSIS.
read(Key, Association_List)
There is no useful case analysis to do on Key. It could be anything.
Association_List could be empty or it could be non-empty. So
read(Key, [Head|Tail]) ->
?What goes here?;
read(Key, []) ->
?What goes here?.
Let's take the empty case first.
Example 7> shows that the result should be {error,instance}.
I am a little surprised that the error term does not include
the Key being sought. Since we're not going to use the Key
in that case, I'll tell the compiler that we *mean* not to use
it by prefixing "_".
read(_, []) ->
{error,instance}.
Now let's take the non-empty case. If we know that the
association list is not empty, do we know enough yet to decide
what to do? No, we don't.
There are going to be two sub-cases.
- We have found what we are looking for.
- We haven't.
Do we know enough to handle example 5> ?
No: we need to know that Head is a pair with Key as its first
element. Some functional languages have what's called
"linear" patterns, where the head of a function may mention
a variable at most once, so that in Haskell we would have to
write
read key ((k,v):alist) | k == key = ...
^^^^^^^^^^ the guard.
Erlang doesn't have that restriction. So we can do
read(Key, [{Key,Value}|_]) ->
% non-empty case, subcase 'found'
?what goes here?;
read(Key, [_|Association_List]) ->
% non-empty case, subcase 'not found'
?what goes here?;
read(_Key, []) ->
{error,instance}.
Now the 'found' subcase will have to return {ok,Value},
and the 'not found' subcase will have to keep on looking.
I'm sure you can figure those out for yourself.
You might actually find the book "The Little Schemer" of use.
The syntax of Scheme is very different from Erlang, and it
doesn't use pattern matching, but the data structures are
quite similar, in particular the lists. The book is all
about teaching recursive programming, mostly using lists.
From Douglas Crockford's review
http://www.crockford.com/javascript/little.html
Despite its flaws, the book has a very loyal
following and that is because it works.
It teaches one thing, a thing that is very
difficult to teach, a thing that every
professional programmer should know, and it
does it really well. These are lessons that
stick with you. You need to grab a sandwich
and study this book.
What is the secret of functional programming?
It is case analysis, case analysis, case analysis!
Cui comparatus indecens erit pavo,
Inamabilis sciurus, et frequens Phoenix.
--- Martial., l. 5. Epig. 38.
Compared with try-catch, a phoenix should be too frequent.
More information about the erlang-questions
mailing list