从Haskell中的列表中求和偶数的平方

时间:2014-09-30 11:50:35

标签: list dictionary haskell filter

我想从列表中加总偶数的平方。我试试这个,但显示错误。

sumaDeCuadrados :: [Int] -> Int
sumaDeCuadrados (x:xs) = sumaListAux (map f l) 0 
    where l = filter even (x:xs) 
          f = x * x
sumaDeCuadrados _ = 0

和sumaListAux是一个定义为..的函数。

sumaListAux :: [Int] -> Int -> Int
sumaListAux [] r = r
sumaListAux (x:xs) r = x + sumaListAux xs r

3 个答案:

答案 0 :(得分:6)

  

将列表中偶数的平方加起来。

Haskell在某些方面是一种声明性语言,因此您可以声明这些内容的含义。

-- declare a list
> let list = [1..10]

-- declare what the even elements of a lsit are
> let evens xs = filter even xs

-- declare what the squares of a list are
> let squares xs = map (^2) xs

并且总和已经存在,sum。所以现在你的句子:

 sum ​​the squares of the even numbers

可以转换为:

> sum . squares . evens $ list
220

答案 1 :(得分:4)

实际问题是,map期望第一个参数是一个函数,它接受一个整数并返回一个整数,但是你传递一个整数。这就是为什么你收到这样的错误信息

Couldn't match expected type `Int -> Int' with actual type `Int'
In the first argument of `map', namely `f'
In the first argument of `sumaListAux', namely `(map f l)'
In the expression: sumaListAux (map f l) 0

因此,您需要将f定义为单独的函数,以便map可以将该函数应用于l。我建议用适当的东西命名函数,比如squarer

squarer :: Int -> Int
squarer x = x * x

sumaDeCuadrados xs = sumaListAux (map squarer (filter even xs)) 0

然后你可以这样称呼它

main = print $ sumaDeCuadrados [1, 2, 3, 4, 5]
-- 20

答案 2 :(得分:2)

基于上面的答案,可以完全使用更高阶的函数来完成。

sumEvenSquares :: (Num a) => [a] -> a
sumEvenSquares xs = sum(map(^2)(filter even xs))

在这种情况下,您可以使用偶数谓词过滤列表,并将函数(^ 2)映射到其上。从这个返回的列表中,您就可以对它进行求和。