Search code examples
functional-programmingsmlfoldml

foldr/foldl with logic operators in SML


I'm trying to build a function in SML using foldr or foldl that will return the logic or and logic and of all elements in a list.

I've tried in this way, using and and or:

fun band x = foldr (op and) true x;
fun bor x = foldr (op or) false x;

And also using andalso and orelse. But I keep receiving error messages such as:

Error: unbound variable or constructor: or

Solution

  • (Answer instead of comment.) Consider using List.all : ('a -> bool) -> 'a list -> bool and List.exists : ('a -> bool) -> 'a list -> bool since they're short-circuiting, unlike List.foldl. There is really no point in folding farther than the first false in band's case, or true in bor's case. That is,

    val band = List.all (fn b => b)
    val bor = List.exists (fn b => b)
    

    One definition for these library functions is found here:

    fun all p []      = true
      | all p (x::xr) = p x andalso all p xr;
    
    fun exists p []      = false
      | exists p (x::xr) = p x orelse exists p xr;
    

    Since the list being fed to band and bor are already of type bool, passing the identity function (fn b => b) will produce the desired truth value. The functions are generic enough to work on any kind of list for which you can apply a predicate for each element, so if you were generating your bool list from some other list, you could avoid that step.