Please, help me. I'm a beginner and I don't really understand

61 Views Asked by At

Write a function min_max : int list -> int * int that takes a non-empty list of numbers, and returns a pair (min, max) of the minimum and maximum of the numbers in the list.

Here is what I've written so far.

fun min_max (n : int list) =
  if null n then NONE
  else
    let
      fun max (n : int list) =
        if null (tl n) then hd n
        else
          let 
            val mn = max (tl n)
          in 
            if hd n > mn then hd n
            else mn
          end 

      fun min (n : int list) =
        if null (tl n) then hd n
        else
          let 
            val mix = min (tl n)
          in 
            if hd n < mix then hd n
            else mix
          end
    in
      SOME (min :: max)
    end;
1

There are 1 best solutions below

0
Chris On BEST ANSWER

Most of what you've written works. Your min and max functions work.

SOME (min :: max)

This doesn't work, though.

This is not how you construct a "pair" or "tuple" of values. Rather:

SOME (min, max)

Moreover, this is now just two functions. You need to apply those functions to your list n to get the results you're looking for.

SOME (min n, max n)

As a suggestion, you can use pattern-matching to simplify your code considerably by avoiding hd and tl and replacing the conditional test on the tail. For instance:

fun min([n]) = n
  | min(h::t) = 
      let 
        val m = min(t) 
      in 
        if h < m then h
        else m 
      end;

But we know that h::t represents a list with at least two elements, so we can bind names to those elements in our pattern.

fun min([n]) = n
  | min(x::(tl as y::z)) = 
      if x < y then min(x::z) 
      else min(tl);

If we evaluate this on a list, we can see how it would proceed.

min([7,8,2,4,6,1,9])
min(7::[2,4,6,1,9])
min([2,4,6,1,9])
min(2::[6,1,9])
min(2::[1,9])
min([1,9])
min(1::[])  ->  min([1]) 
1

This also has the benefit of being tail-recursive.