Search code examples
smlsmlnj

Error: case object and rules don't agree [overload conflict]


I am working on a function that finds the largest number in a list.

fun maxValue(xs) =
  case xs of
      [] => []
    | first::rest => if ((first)>hd(rest))
                     then maxValue(first :: tl(tl(rest)))
                     else maxValue(rest)
val list = [1,2,4,8,3]
val ans = maxValue list

However I am getting the following error:

Standard ML of New Jersey v110.78 [built: Thu Aug 31 03:45:42 2017]
= stdIn:2.5-6.40 Error: case object and rules don't agree [overload conflict]
rule domain: [> ty] list list
object: [> ty] list
in expression:
(case xs
  of :: (x,nil) => x
   | :: (xs,rest) =>
       if hd <exp> > hd <exp>
       then maxValue (<exp> :: <exp>)
       else maxValue (tl <exp>))

I am not understanding what the error means, why the code doesn't compile. Is there something I am missing and how do I fix this?

Edit: Changed certain variable names from xs to first for clarity.


Solution

  • I have a couple of questions about your function:

    1. Where are you returning the max value?
    2. Why are you trying to get the head of first? In your example first doesn't has a head because it is 1, i. e. the head of the list you are passing as argument
    3. Why are you trying to get the tail of the tail of rest?

    To solve this class of problems with recursion I use a helper function that holds the recursive structure as first argument and the possible result as the second argument. This is my attempt:

    fun maxValue xs =
      let
        fun helper xs chosen =
          case xs of
              [] => chosen
            | first :: [] =>
                if first > chosen
                then first
                else chosen
            | first :: rest =>
                if first > hd rest
                then helper rest first
                else helper rest (hd rest)
      in
        helper xs 0
      end
    

    In the case of a null list I'm simply returning 0 to avoid complicating.

    Lately I'm using Poly/ML instead of SML/NJ. The errors seems more friendly