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.
I have a couple of questions about your function:
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 argumentrest
?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