2
\$\begingroup\$

I implemented and and or:

-- or is like and, only it returns True if 
-- any of the boolean values in a list is True.
or' :: [Bool] -> Bool
or' []     = False
or' (x:xs) = x || or' xs 

--and takes a list of boolean values and returns True only if 
-- all the values in the list are True.
and' :: [Bool] -> Bool
and' [] = False
and' (x:xs) = x && and' xs

Is pattern matching the most elegant solution here?

Also, should or' [] and and' [] return False? It makes sense for them to do so when passing in a non-null input.

Example: or' [False, False]

But, how about the behavior of or' [] or and' []? Does False make sense here?

\$\endgroup\$

3 Answers 3

6
\$\begingroup\$

Your or' function is fine.

and' [] should return True — that's what the built-in and [] does. As it is, your and' function is broken, and always returns False:

*Main> and' [True]
False
\$\endgroup\$
8
\$\begingroup\$

Consider that Bool is an algebraic data structure like any other in Haskell. Pattern matching is the most elegant solution, but you can use even more of it to be even more elegant!

-- import Prelude hiding (or)

or :: [Bool] -> Bool
or []         = False
or (False:bs) = or bs
or (True :_ ) = True
\$\endgroup\$
1
  • \$\begingroup\$ I like that this solution works based on first principles, not even relying on || and &&. \$\endgroup\$ Commented May 1, 2014 at 10:28
4
\$\begingroup\$

Also, should or' [] and and' [] return False? It makes sense for them to do so when passing in a non-null input.

No, it makes sense only for or'. Apart from translating them to basic mathematic quantifiers "Is any of the items true?" (False for no items) and "Are all of the items true?" (True for no items), you can try to evaluate your function with an example one-item list and confirm whether it meets the expected results:

or' [False]       = False
False || or' []   = False
False || False    = True
--       ^^^^^

and' [True]       = True
True && and' []   = True
True &&  True     = True
--       ^^^^

Is pattern matching the most elegant solution here?

It's OK, but most recursive functions can be written more concisely (= elegant?) with folds:

or' = foldr (||) False
and' = foldr (&&) True
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.