Haskell的基本总结

dc.*_*dc. 4 recursion haskell

我正在练习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)
Run Code Online (Sandbox Code Playgroud)

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

Avi*_*ilo 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)
Run Code Online (Sandbox Code Playgroud)

  • @dc你的问题本来就是调用`show(summation 0)`或类似的东西.问题是求和只适用于1个参数,因此它返回一个从Integer到Integer的函数,它没有`Show`的实例.另一方面`show(求和0 10)`会起作用.您可能有正确的解决方案,但外围问题导致您认为它是错误的.上面的代码从不调用`show`,所以这不是问题所在. (2认同)

Ezr*_*zra 10

快速回答:

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

然后你可以简单地说:

summation x y = sum [x .. y]
Run Code Online (Sandbox Code Playgroud)

这个解决方案假设x小于y,你可以通过说:

summation x y = sum [min x y .. max x y]
Run Code Online (Sandbox Code Playgroud)

定义sum:

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

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

:browseGHCI中的命令是我最近发现的,我希望我能早点发现.

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

sum xs y = foldl (+) 0 xs
Run Code Online (Sandbox Code Playgroud)

"无意义"风格的等价物:

sum = foldl (+) 0
Run Code Online (Sandbox Code Playgroud)

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


进一步阅读:

你会注意到我使用了这个功能foldl.此功能"折叠"输入列表.要"掌握"函数式编程,知道如何成为fold最基本和最重要的概念之一.一个很好的咨询资源是来自Haskell Wiki的折叠页面.