Search code examples
smlnj

How to check if a value exists in a list in smlnj


I'm working on some homework and I need to create a function that checks if a value exists in a list. If it does it will return true, otherwise it returns false. I have an idea of how to do it but I keep getting errors. I think it may be due to my lack of knowledge of syntax and style as this is my first time coding in sml.

I created the function exist and am passing a value and list in as a tuple.

fun exist (x, []) =     
if x = hd ([]) then true        
else if x  = tl ([]) then true    
else false;

Sorry if this code is laughably incorrect but I get the error message:
" stdIn:2.6 Warning: calling polyEqual
stdIn:3.11 Warning: calling polyEqual
stdIn:1.6-4.11 Warning: match nonexhaustive (x,nil) => ...
val exist = fn : ''a list * 'b list -> bool "

and I'm not really sure how to fix this. Any help would be great.


Solution

  • Your function is pattern-matching on [], so it can only ever match the empty list.
    Also, hd [] and tl [] are both errors since the empty list has neither head nor tail.

    Further, if some_condition then true else false is equivalent to some_condition.
    (And if some_condition then false else true is equivalent to not some_condition.)
    Logical expressions are usually more readable than chains of conditionals.

    And you forgot to recurse; you need to use exist on the tail of the list if the first element is not what you're looking for.

    Either stick to pattern matching:

    fun exist (_, []) = false
      | exist (x, y::ys) = x = y orelse exist (x, ys)
    

    or don't use it:

    fun exist (x, xs) = not (null xs) andalso (x = hd xs orelse exist (x, tl xs)) 
    

    Pattern matching is often the most readable solution and gives a clear picture of the various cases.

    (You seem to have mixed the two forms, treating [] as an identifier rather than a type constructor.)