简体   繁体   中英

Implement the functions using map and foldr, haskell

I have two functions. The first one gives true if all elements of the list are zero

allZero :: [Int] -> Bool
allZero [] = False
allZero [0] = True
allZero (x:xs)
  | x == 0 && allZero xs = True
  |otherwise = False

The second function gives true if at least one element of the list is zero

oneZero :: [Int] -> Bool
oneZero [] = False
oneZero (x:xs)
   | x == 0 = True
   | otherwise = oneZero xs

Maybe there is another way to solve this problems. For example with map or foldr? Thank you

foldr basically takes your guard as its folding function:

allZero = foldr (\x acc -> x == 0 && acc) True

acc (for acc umulator) is the already-computed value of the recursive call. Being right-associative, the first non-zero value in the list short-circuits the evaluation of the fold function on the rest of the list.

(Note that allZero [] == True by convention. The "hypothesis" is that allZero xs is true, with evidence in the form of a non-zero element to falsify the hypothesis. No elements in the list, no evidence to contradict the hypothesis.)

I leave it as an exercise to adapt this to compute oneZero .

foldr function works so:

Suppose, you have list [1, 2, 3] . Let's write this list as (:) 1 ((:) 2 ((:) 3 [])) , where each element has type a . Function foldr takes function f of a -> b -> b type and starting element z of b type, and just replace [] to z and : to f . So, foldr fz ((:) 1 ((:) 2 ((:) 3 []))) == f 1 (f 2 (f 3 z)) .

So, you can define your functions so:

allZero = foldr (\x -> x == 0 &&) True

oneZero = foldr (\x -> x == 0 ||) False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM