我一直在尝试创建一个递归函数,它接受一个整数列表并得到平方根的总和。 我来自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
我只做了一点点递归,我找不到任何能以我理解的方式解释它的地方
答案 0 :(得分:2)
sumsquares :: Int a => [a] -> a
类型签名很奇怪。 Int
是一种类型,但您使用的是类语法。你真正想要的是什么(&#34;一个整数列表&#34;)是:
[Integer] -> Integer
你也把f
作为一个论点而已。这让我觉得你认为Int a =>
是一个论点。不是。 X a =>
形式的任何内容都是一个类型类约束,它对函数的arity没有贡献。
然后我们有:
sumsquares f [] = "List is Empty"
这是不合理和不正确的。一般来说,人们会期望空列表的总和为0
或mempty
(对于更复杂的主题而言)。 "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
。另请注意,Integer
和Int
并不相同。 (Int
通常为32位,而Integer
可以容纳数千位。)
不确定f
参数应该是什么。 (在你的签名中也没有提到它,所以它不会起作用。)
您不能让一个等式返回一个字符串("List is Empty"
)而另一个等式返回一个数字。他们必须返回数字。我建议没有数字加起来为零。
你可能想写类似
的东西sumsquares :: [Integer] -> Integer
sumsquares [] = 0
sumsquares (x:xs) = isqrt x + sumsquares xs
你明白为什么会有效吗?空列表的sumsquare
只是零,否则将isqrt
应用于第一个元素,递归地对剩余元素求和,并添加两个结果。