haskell - Haskell 递归函数返回一个布尔值
问题描述
我正在尝试编写一个递归函数来添加一个数字列表并返回Bool
总和是否可被 5 整除。但是,我无法让它工作。
div5 :: [Int] -> Bool
div5 (x:xs)
| total `mod` 5 == 0 = True
| otherwise = False
where
total = total + x
解决方案
这个表达式where total = total + x
没有多大意义,它在评估它时会导致一个无限循环,因为你说它total
等价于total + x
, 因此(total + x) + x
,((total + x) + x) + x
等等。
一个简单的解决方案是利用对sum :: (Foldable f, Num a) => f a -> a
数字求和,然后检查结果是否等于0
:
div5 :: (Foldable f, Integral a) => f a -> Bool
div5 xs = mod (sum xs) 5 == 0
或无点表示法:
div5 :: (Foldable f, Integral a) => f a -> Bool
div5 = (0 ==) . (`mod` 5) . sum
例如:
Prelude Data.List> div5 [1,4,2,5]
False
Prelude Data.List> div5 [1,4,2,5,3]
True
这不仅适用于列表,也适用于所有Foldable
类型,所以Maybe
,Tree
等等。
但是,如果值非常大,或者元素的数量非常大,这会给出不正确的结果,因为这样总和不再可以用数字类型表示。但是我们不需要计算全和,我们可以先计算(`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)
您可以将其转换为带有辅助函数的递归函数,该函数执行递归以求和值(或它们的模块 5 等效项)。我把它留作练习。
推荐阅读
- android - 错误:[RoomProcessor:MiscError] androidx.room.RoomProcessor 无法处理此类,因为并非所有依赖项都可以解决
- android - LazyColumn 不适合其在对话框中的内容
- opencl - get_local_id(1) 返回零值
- node.js - Node.js (Express) Firebase 存储大多数功能不起作用
- python - 未正确创建 Django formset 模型
- python - 检查用户活动的任务
- kendo-ui - 如何为剑道反应网格的导出pdf和excel添加选项?
- c++ - 如何从字符串中删除连续出现两次以上的字符?
- git - git pull 和 git pull origin 有什么区别
- node.js - 使用 promise 更正嵌套异步函数的错误处理