简体   繁体   English

Haskell 递归函数返回一个布尔值

[英]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.我正在尝试编写一个递归函数来将一个数字列表相加并返回一个关于总和是否可以被 5 整除的Bool 。但是,我无法让它工作。

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.表达式where total = total + x没有多大意义,在评估这个时会导致无限循环,因为你说total等价于total + x ,因此(total + x) + x , ((total + x) + x) + x等。

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 :一个简单的解决方案是利用sum :: (Foldable f, Num a) => fa -> a对数字求和,然后检查结果是否等于0

div5 :: (Foldable f, Integral a) => f a -> Bool
div5 xs = mod (sum xs) 5 == 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.这不仅适用于列表,还适用于所有Foldable类型,因此MaybeTree等。

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:然而,我们不需要计算全和,我们可以先计算每个元素的(`mod` 5) ,然后将其求和,其中每个和再次是mod 5 ,然后我们得到和mod 5的结果,并且因此我们可以检查这是否为 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).您可以将其转换为带有辅助函数的递归函数,该函数执行递归以求和值(或它们的模块 5 等效项)。 I leave this as an exercise.我把它留作练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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