haskell - 你能帮我理解这段代码是如何工作的吗?我是haskell的初学者
问题描述
我正在查找一些带有答案的 Haskell 练习。这是练习:
假设您有一个函数
rainfall
可以计算给定一周内您所在城市的降雨量(其中周数从 1 开始编号)type WeekNumber = Int rainfall :: WeekNumber -> Double -- assume this function exists
完成以下函数的定义:
mostRain :: WeekNumber -> Double mostRain n | n < 1 = 0 | otherwise = -- (complete this case)
您的解决方案必须是递归的。提示:函数 max 可能有用。请注意,您不必为函数提供定义
rainfall
。
答案:
import Data.List
import Data.Maybe
import Test.QuickCheck
-- 1 ----------------
type WeekNumber = Int
rainfall :: WeekNumber -> Double
rainfall n = fromIntegral (n `mod` 7) * 3.9
mostRain :: WeekNumber -> Double
mostRain n | n < 1 = 0
| otherwise = rainfall n `max` mostRain (n - 1)
我真的希望有人可以帮助向我解释他们是如何得出这个数字 3.9(n `mod` 7) * 3.9
这里实际发生了otherwise = rainfall n `max` mostRain (n - 1)
什么?
解决方案
首先,正如@AJFarmar 指出的那样,编写rainfall
函数不是练习的一部分。答案只是提供了一个任意定义,因此您可以测试解决方案,而数字 3.9 只是凭空拉出来的,以使降雨量看起来“有趣”:
> rainfall 1
3.9
> rainfall 2
7.8
>
您实际上并不需要了解表达式:
fromIntegral (n `mod` 7) * 3.9
确实可以理解解决方案,但是如果您有兴趣,它会接受输入整数n
,计算n `mod` 7
(这是n
除以 7 时的余数,因此变为 1、2、3、4、5、6、7、8, 9, 10 转换为 1, 2, 3, 4, 5, 6, 0, 1, 2, 3),并在乘以 3.9 之前将结果从整数转换为双精度数。因此,例如,这给出了第 1 到第 10 周的降雨量,如下所示:
> map rainfall [1..10]
[3.9,7.8,11.7,15.6,19.5,23.4,0.0,3.9,7.8,11.7]
>
为了理解 之后的部分解决方案otherwise
,首先让我们重写它以摆脱特殊的反引号:
mostRain :: WeekNumber -> Double
mostRain n | n < 1 = 0
| otherwise = max (rainfall n) (mostRain (n - 1))
这个定义表明,计算第 1 周到第 n 周的最多降雨量,即mostRain n
,将定义为0
if n < 1
,否则由以下表达式定义:
max (rainfall n) (mostRain (n - 1))
该表达式计算两个数字中的最大值,即 的值rainfall n
(即周降雨量n
)和 的值mostRain (n - 1)
。这是一个递归调用,它将计算第 1 周到第 1 周看到的最多降雨量n-1
。
所以,这实际上是说从第 1 周到第 n 周的最多降雨被定义为 (1) 第 n 周的降雨量和 (2) 前几周看到的最多降雨中的最大值。或者,您可以将其视为按如下步骤执行计算:
mostRain 3
= max (rainfall 3) (mostRain 2)
= max (rainfall 3) (max (rainfall 2) (mostRain 1))
= max (rainfall 3) (max (rainfall 2) (max (rainfall 1) (mostRain 0))
= max (rainfall 3) (max (rainfall 2) (max (rainfall 1) 0)
如果我们填写模拟降雨量,您可以看到它最终如何计算最大值:
= max 11.7 (max 7.8 (max 3.9 0)
= max 11.7 (max 7.8 3.9)
= max 11.7 7.8
= 11.7
推荐阅读
- java - 即使我的 for 循环计数器通过减去 1 来调整长度,我仍然收到“java.lang.StringIndexOutOfBoundsException”
- flutter - Flutter SDK 安装在受保护的文件夹中,可能无法正常运行
- entity-framework - 为什么这个模型实现 IEnumerable 时会生成阴影属性?
- python-2.7 - 从文件中读取数字到多维数组
- android - 有没有办法在执行登录按钮意图之前检查电子邮件和密码编辑文本是否已填写?
- excel - 将 Google Apps 脚本转换为 VBA
- c++ - 比较 Char 数组
- java - 尝试将本机 SQL 转换为 HQL 时出现异常?
- python - 为什么 python 2 和 3 对于某些十六进制值有不同的打印输出?
- python-3.x - 使用 Pandas 找到每个唯一组的最高值