简体   繁体   中英

Haskell Recursive Function Returning One Bool

I am trying to write a recursive function to add up a list of numbers and to return a Bool of whether the sum is divisible by 5. However, I can not get this to work.

div5 :: [Int] -> Bool 
div5 (x:xs)  
  | total `mod` 5 == 0 = True
  | otherwise = False
  where
    total = total + x

The expression where total = total + x does not make much sense, it will result in an infinite loop when evaluating this, since you say that total is equivalent to total + x , and thus (total + x) + x , ((total + x) + x) + x , etc.

A simple solution is to make use of sum :: (Foldable f, Num a) => fa -> a to sum up the numbers, and then check if the result is equivalent to 0 :

div5 :: (Foldable f, Integral a) => f a -> Bool
div5 xs =  == 0

or in point-free notation:

div5 :: (Foldable f, Integral a) => f a -> Bool
div5 = (0 ==) . (`mod` 5) . sum

for example:

Prelude Data.List> div5 [1,4,2,5]
False
Prelude Data.List> div5 [1,4,2,5,3]
True

This does not only work for lists, but also for all Foldable types, so Maybe , Tree , etc.

This however give incorrect results if the values are very large, or the number of elements is very large, since then the sum can no longer be representable by the number type. We however do not need to calculate the full sum, we can first calculate the (`mod` 5) of each element, and sum it up where each sum again is mod 5 , we then obtain the result of the sum mod 5 , and thus we can check if this is 0:

import Data.List(foldl')

div5 :: (Foldable f, Integral a) => f a -> Bool
div5 xs = foldl' f 0 xs == 0
    where f y = (`mod` 5) . (y+) . (`mod` 5)

You can turn this into a recursive function with a helper function that performs recursion to sum up values (or their module 5 equivalent). I leave this as an exercise.

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