Search code examples
erlanginference

Erlang inference


The following source doesn't compile because Stopover is unbound.

I'm new to Erlang, how can I rewrite it?

-module(distances).
-export([ path/2 ]).

path( madrid, paris ) ->
   { km, 1049 };
path( paris, moscou ) ->
   { km, 2482 };
path( moscou, berlin ) ->
   { km, 1603 };
path( From, To ) ->
   path( From, Stopover ) + path( Stopover, To ).

The usage of this module maybe:

path( madrid, moscou ).

And the epected answer should be { km, 3531}.


Solution

  • The following source doesn't compile because Stopover is unbound.

    I'm new to Erlang, how can I rewrite it?

    Look at this code:

    -module(a).
    -compile(export_all).
    
    do_stuff() ->
        Stopover.
    

    Here's what happens when I try to compile it:

    a.erl:5: variable 'Stopover' is unbound

    The variable Stopover was never assigned a value, so erlang has no idea what should be returned by the function do_stuff(). You are doing something similar here:

    path( From, Stopover ) + path( Stopover, To ).
    

    The variables From and To are parameter variables for the function path(), and when path() is called, e.g. path(madrid, moscow), then madrid will be assigned to the variable From, and moscow will be assigned to the variable To. Note, however, that nowhere do you assign any value to the variable Stopover.

    You need to redefine path() to look like this:

    path(From, To, Stopover) ->
    

    Next, you should try to see if adding tuples actually works:

    2> {km, 5} + {km, 3}.
    ** exception error: an error occurred when evaluating an arithmetic expression
         in operator  +/2
            called as {km,5} + {km,3}
    3> 
    

    Nope!

    What you need to do is use pattern matching to extract the distance, an integer, from each tuple, then add the two integers:

    {km, Distance1} = path( From, Stopover ),
    ...             = path(Stopover, To),
    
    {km, Distance1 + Distance2}.