使用Recursion获取列表的和sqrt

时间:2014-12-09 13:11:11

标签: haskell

我一直在尝试创建一个递归函数,它接受一个整数列表并得到平方根的总和。 我来自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

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

2 个答案:

答案 0 :(得分:2)

您的代码如何不可编译

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

类型签名很奇怪。 Int是一种类型,但您使用的是类语法。你真正想要的是什么(&#34;一个整数列表&#34;)是:

[Integer] -> Integer

你也把f作为一个论点而已。这让我觉得你认为Int a =>是一个论点。不是。 X a =>形式的任何内容都是一个类型类约束,它对函数的arity没有贡献。

然后我们有:

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

答案 1 :(得分:0)

嗯,isqrt看起来不错。

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

不确定f参数应该是什么。 (在你的签名中也没有提到它,所以它不会起作用。)

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

可能想写类似

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

你明白为什么会有效吗?空列表的sumsquare只是零,否则将isqrt应用于第一个元素,递归地对剩余元素求和,并添加两个结果。