首页 > 解决方案 > 你能帮我理解这段代码是如何工作的吗?我是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)什么?

标签: haskell

解决方案


首先,正如@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,将定义为0if 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

推荐阅读