在Haskell中使用保护程序编写产品函数

时间:2011-11-15 04:18:28

标签: function haskell if-statement product

我需要以两种方式编写函数product

  1. 使用警卫
  2. 使用if-then-else
  3. 这样函数就会返回m到n的乘积。

    示例:

    product 3 5

    返回3 * 4 * 5 = 60

    由于

1 个答案:

答案 0 :(得分:8)

这听起来像是一个家庭作业问题,所以不要只是删掉你的代码,让我们解决这个问题:

输入签名

Haskell是一种具有强类型的函数式语言,因此最好从编写函数的类型签名开始。您的示例显示了两个整数参数和一个整数返回值。我们将其编码为:

product :: Int->Int->Int

这读作“product是一个需要两个Int并返回Int的函数。” (还有其他更正确的方法来阅读这个,但那是另一天)

<强>递归

我们将在Haskell中使用一个通用模式。因为在这种情况下我们需要跟踪中间值,所以我们将编写第二个函数product',它将采用额外的参数,即正在运行的产品。

product' :: Int->Int->Int->Int
product' accumulator current final = product' (accumulator*current) (current+1) final

在每次迭代时,这将采用最近的累计值乘以当前值并将其作为新累加器传递,它将获取当前值并将其作为新电流加1,并将最终传递给最终值。为了开始,我们编写了我们的原始函数:

product i f = product' 1 i f

或无分数符号

product = product' 1

问题是product'代码将永远循环。我们需要一种方法来阻止我们当前的流量大于最终目标。

警卫

而不是重写关于警卫模式的书send you to the book。简而言之,在你做某事之前,他们会给你一个布尔值。我们将使用它们来阻止我们的递归。

product' :: Int->Int->Int->Int
product' accumulator current final 
    | current <= final = product' (accumulator*current) (current+1) final
    | otherwise = accumulator

只要current小于或等于final,一旦不是最终答案在累加器中,我们会继续递归。

如果 - 则 - 否则

警卫可以用机械方式替换为if构造(可能深度嵌套)。

product' :: Int->Int->Int->Int
product' accumulator current final = 
  if current <= final 
    then product' (accumulator*current) (current+1) final
    else accumulator

最后的想法

不要写这样的代码。有许多wonderfully generic higher level function只做这些类型的事情。这是编写产品的更好方法:

product i f = foldl (*) 1 [i..f]