我已经通过递归编写了一个onRange函数的练习,即:给出一个带有列表的两个数字(表示范围),它应该返回一个新列表,其中包含两个之间的所有数字,包括两个提供的范围编号。
显然,如果列表为空,则应该是基本情况之一 inRange a b [] = [],但除此之外,我完全迷失了。我尝试过使用受保护的陈述,但我仍然非常迷失。
答案 0 :(得分:3)
总是递归由两部分组成:
一个或多个基本案例,例如空列表:
inRange _ _ [] = []
一个或多个递归案例(或归纳案例)。显然,当列表不为空时就是这种情况。
现在对于后者,有两个选项:列表的第一个数字在范围内,或者不是。如果是,我们列举它,如果不是,我们不列举:
inRange a b (x:xs) | a <= x && x <= b = x : tl
| otherwise = tl
where tl = inRange a b xs
所以完整的实现如下:
inRange a b (x:xs) | a <= x && x <= b = x : tl
| otherwise = tl
where tl = inRange a b xs
inRange _ _ _ = []
这里我们在底部写了基本案例:优点是 - 至少在概念上 - Haskell从上到下进行评估,显然列表不太可能是空的。
此外,我们可以对所有参数使用不关心(_
),以便我们确定所有可能的情况都被覆盖,因此该函数至少是完全的(对于任何类型的输入,意味着你将总是收到输出,虽然这显然不能证明是正确的。)
答案 1 :(得分:0)
这个怎么样?
inRange :: Int -> Int -> [Int]
inRange x y | x == y = [x]
| x < y = x : inRange (x + 1) y
您实际上不必将列表作为此
的参数传递