Search code examples
smlnj

SML Comparing datatype list and hd() tl() function


For 2 datatype like this.

datatype flight = F of int * int; 
datatype flights = Fs of flight list;

I want to make a function that can check if (a,b) is in flights or not.

Example:

val reachable = fn : flights * (int * int) -> bool

reachable (Fs [F(0,1), F(1,0)], (0, 1));
val it = true : bool

I have no idea how can i compare a (int*int) to flights.

I use

fun get_f_x (F(x,y)) = x;

to get the first integer in flight.

But when i try to do the same thing to flights.

I do it like below:

fun test_hd(Fs[i,_]) = i;

In order to get the first flight out for the flights. But it can only take flights with 2 flight only (Fs [F(0,1), F(1,0)]) If flight have more than 2 element, it show error.

Similarly

fun test_tl(Fs[_,i]) = i;

have the same problem.

How can I make a hd and tl for flights? Or what is the correct way to think about this problem?


Solution

  • Not having seen the errors you're encountering, it's hard to say, but looking at the code you've shown, I suspect in-exhaustive pattern matching is a factor. With that in mind, let's look at a way of breaking down the recursion and pattern matching involved.

    If you want to see if a particular flight is in flights, first we need to start with what we absolutely know: If a flights value contains no values in its list, then the answer must be false, no matter what we're looking for.

    fun reachable(Fs([]), _) = false
    

    What if there is something in that list? Well, let's check the first element to see if it's what we are looking for.

    fun reachable(Fs([]), _) = false
      | reachable(Fs(F(x) :: xs), flt) = flt = x
    

    But what about the rest, if that one doesn't match? We'd need to check the rest of the list.

    fun reachable(Fs([]), _) = false
      | reachable(Fs(F(x) :: xs), flt) = 
          flt = x orelse reachable(Fs(xs), flt)