Haskell的基本总结

时间:2011-03-22 03:27:11

标签: haskell recursion

我正在练习Haskell,并编写一个求和函数,它接受两个数字(上限和下限)并进行求和。

即,summation 0 10将返回55

我可以让它主要工作,但是很难找到如何仅使用两个参数来获取它。

这是我到目前为止所做的:

summation :: Integer -> Integer -> Integer -> Integer
summation x y sum =
    if (y<x) then
        sum
    else
        summation x (y-1) (sum+y)

所以这很好用,但我需要做summation 0 10 0才能让它正常工作。我不知道如何才能在Haskell中只使用两个参数。

3 个答案:

答案 0 :(得分:10)

你把它包起来。

summation :: Integer -> Integer -> Integer
summation x y = summation' x y 0

summation' :: Integer -> Integer -> Integer -> Integer
summation' x y sum =
    if (y<x) then
        sum
    else
        summation' x (y-1) (sum+y)

答案 1 :(得分:10)

快速回答:

一种简单的方法是使用sum中的Data.List函数。

然后你可以简单地说:

summation x y = sum [x .. y]

此解决方案假设x小于y,您可以通过以下方式解决此问题:

summation x y = sum [min x y .. max x y]

定义sum

由于您正在学习Haskell,因此了解sum如何工作可能很重要,而不仅仅是知道它存在。对我来说,最初克服的最大障碍是编写已经存在的太多功能;特别是因为我不知道如何有效地写它们。

Hoogle在这方面是一个很好的帮助:它是一个搜索引擎,允许你搜索Haskell函数。这对于提高工作效率来说是一件好事,因为你可以花时间处理你的问题,而不是对前奏的一半做出糟糕的重写。它也非常适合学习,因为Hackage上有大多数功能的源代码链接。 Prelude和其他“基本”库(如Data.List)的源代码对初学者来说非常容易获取,并且会为“聪明的孩子”如何做事提供大量见解。

GHCI中的:browse命令是我最近发现的,我希望我能早点发现。

无论如何,定义sum的一种方法是使用折叠:

sum xs y = foldl (+) 0 xs

"pointless" style中的等价物:

sum = foldl (+) 0

我通常更喜欢第一种配方,但知道第二种配方的工作方式和原因会对您的旅程有所帮助。


进一步阅读:

你会注意到我使用了函数foldl。此功能“折叠”输入列表。要“掌握”函数式编程,了解如何fold是最基本和最重要的概念之一。一个很好的咨询资源是来自page on foldsHaskell Wiki

答案 2 :(得分:4)

你可以像高斯那样做。

summation begin end
    | end < begin = summation end begin
    | otherwise   = n * (2*a + (n-1)*d) `div` 2
  where a = begin
        d = 1
        n = end - begin + 1

代码是来自http://mathcentral.uregina.ca/QQ/database/QQ.02.06/jo1.html的明显字面翻译(在该页面的一点点:S = n[2a + (n-1)d]/2