【问题标题】:Using Recursion to get the sum sqrt of a list使用递归获取列表的总和
【发布时间】:2014-12-09 23:05:43
【问题描述】:

我一直在尝试创建一个递归函数,它接受一个整数列表并获得平方根的总和。 我来自 c#,我对 haskell 很陌生。我觉得好像我遇到了理解障碍

我遇到了类型问题,所以我尝试制作一个整数 sqrt 来帮助自己,但最终让自己更加困惑..

isqrt :: Integer -> Integer
isqrt = floor . sqrt . fromIntegral

sumsquares :: Int a => [a] -> a
sumsquares f [] = "List is Empty"
sumsquares f (x:xs) | sum . isqrt  x | x <- xs

我只做了一点递归,我找不到任何地方能以我理解的方式真正解释它

【问题讨论】:

  • 确实意识到这是不适合递归的情况之一,不是吗? :-)

标签: haskell


【解决方案1】:

您的代码为何无法编译

sumsquares :: Int a => [a] -> a

类型签名很奇怪。 Int 是一种类型,但您使用的是类语法。您真正的意思(“整数列表”)是:

[Integer] -> Integer

您还将一个根本不存在的f 作为参数。这让我觉得你认为Int a =&gt; 是一个论点。它不是。 X a =&gt; 形式的任何内容都是类型类约束,不会影响函数的数量。

那么我们有:

sumsquares f [] = "List is Empty"

这是不合理和不正确的。一般来说,一个空列表的总和是0mempty(这是一个更复杂的主题)。 "List is Empty"String(除非有 OverloadedString),因此该行甚至无法编译。

最后:

sumsquares f (x:xs) | sum . isqrt  x | x <- xs

我不知道你想在这里做什么,但| 用于条件句。例如:

sumSquares :: [Integer] -> Integer
sumSquares x
    | null x    = 0
    | otherwise = (isqrt . head $ x) + tail x

显式递归解决方案

应该是这样的:

sumSquares :: [Integer] -> Integer
sumSquares []       = 0
sumSquares (x:xs)   = isqrt x + sumSquares xs

map 的解决方案

使用map,很简单:

sumSquares :: [Integer] -> Integer
sumSquares = sum . map isqrt

【讨论】:

  • 谢谢,这很有帮助
【解决方案2】:

嗯,isqrt 看起来不错。

sumsquares 上的类型签名错误; Int 不是一个类,它是一个类型。所以你可能想写[Int] -&gt; Int。另请注意,IntegerInt 并不相同。 (Int 通常是 32 位,而 Integer 可以容纳 数千 位。)

不确定f 参数的用途。 (你的类型签名中也没有提到它,所以这不起作用。)

您不能让一个方程返回一个字符串 ("List is Empty"),而另一个方程返回一个数字。他们都必须返回数字。我建议没有数字加起来为零。

可能想写类似

sumsquares :: [Integer] -> Integer
sumsquares [] = 0
sumsquares (x:xs) = isqrt x + sumsquares xs

你明白为什么会这样吗?空列表的sumsquare 正好为零,否则将isqrt 应用于第一个元素,递归地对其余元素求和,然后将两个结果相加。

【讨论】:

    猜你喜欢
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多