在haskell中编写递归的inRange函数

时间:2015-11-27 15:41:27

标签: haskell recursion

我已经通过递归编写了一个onRange函数的练习,即:给出一个带有列表的两个数字(表示范围),它应该返回一个新列表,其中包含两个之间的所有数字,包括两个提供的范围编号。

显然,如果列表为空,则应该是基本情况之一 inRange a b [] = [],但除此之外,我完全迷失了。我尝试过使用受保护的陈述,但我仍然非常迷失。

2 个答案:

答案 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

您实际上不必将列表作为此

的参数传递