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

1 haskell if-statement product function

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

  1. 使用卫兵
  2. 使用if-then-else

这样函数返回m到n的乘积.

例:

product 3 5

返回3*4*5 = 60

谢谢

Joh*_*ler 8

这听起来像是一个家庭作业问题,所以不要只是在你身上放下代码,让我们解决这个问题:

输入签名

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

product :: Int->Int->Int
Run Code Online (Sandbox Code Playgroud)

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

递归

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

product' :: Int->Int->Int->Int
product' accumulator current final = product' (accumulator*current) (current+1) final
Run Code Online (Sandbox Code Playgroud)

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

product i f = product' 1 i f
Run Code Online (Sandbox Code Playgroud)

或以无点符号表示

product = product' 1
Run Code Online (Sandbox Code Playgroud)

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

逆天

而不是重写关于警卫模式的书,我会把你送到书上.简而言之,在你做某事之前,他们会给你一个布尔值.我们将使用它们来阻止我们的递归.

product' :: Int->Int->Int->Int
product' accumulator current final 
    | current <= final = product' (accumulator*current) (current+1) final
    | otherwise = accumulator
Run Code Online (Sandbox Code Playgroud)

只要current小于或等于final我们继续递归一旦它不是最后的答案是在累加器中.

IF-THEN-ELSE

防护装置可以用if机械方式替换为构造(可能是深度嵌套).

product' :: Int->Int->Int->Int
product' accumulator current final = 
  if current <= final 
    then product' (accumulator*current) (current+1) final
    else accumulator
Run Code Online (Sandbox Code Playgroud)

最后的想法

不要写这样的代码.有许多非常通用的高级功能可以完成这些类型的事情.这是编写产品的更好方法:

product i f = foldl (*) 1 [i..f]
Run Code Online (Sandbox Code Playgroud)

  • luqui,谢谢你.我修复了代码.OP只是在11月遇到了这个问题,这强烈暗示了一个调查课程.Guards和If-then-else是编写这个函数的两种最糟糕的方式,这意味着教师只是在刷函数语言,而恕我直言的工作非常糟糕.我会尽我所能给予帮助,希望Alyx可能真的喜欢Haskell,而不是像大多数同学那样毫无希望地发现它. (6认同)
  • 我很欣赏解释的努力,但你确实意识到,当人们在他们的家庭作业上寻求帮助时,除了你的解释之外,如果你给他们一个完整的实施,那么你的解释不太可能是正念的.幸运的是......我认为......你所有的代码示例都被破坏了,所以这个效果至少是以某种方式改变了. (2认同)