Haskell zipWith
Haskell zipWith
我想总结一个压缩列表。
averageGrade :: [Float] -> [Int] -> Float
averageGrade [0.75 , 0.25] [6, 4] , result: 0,75*6 + 0.25*4 = 5.5
当我进入 ghci 并执行以下操作时:
sum(zipWith (*) [0.75, 0.25] [6, 4])
我得到了我想要的。
但是在代码中我遇到了一个错误,我不知道为什么。
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b
| a == [] = 0
| b == [] = 0
| otherwise = (sum(zipWith (*) a b))
如果我想编译它,我会遇到以下失败:
Couldn't match type ‘Int’ with ‘Float’
Expected type: [Float]
Actual type: [Int]
In the third argument of ‘zipWith’, namely ‘b’
In the first argument of ‘sum’, namely ‘(zipWith (*) a b)’
Failed, modules loaded: none.
您不能 *
两个具有不同类型的数字,例如 Float
和 Int
。您需要显式转换其中之一,以便它们具有相同的类型(Float
,在您的情况下)。
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b
| a == [] = 0
| b == [] = 0
| otherwise = sum (zipWith (\ x y -> x * fromIntegral y) a b)
请注意,您实际上不需要检查 ==[]
个案例,因为 zipWith
returns []
是这些案例,而 sum [] == 0
.
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b = sum (zipWith (\ x y -> x * fromIntegral y) a b)
您可以 (*)
不同的类型,因为它们是 Num
类型 class 的成员。您可以向类型签名添加 Num
和 Eq
约束,例如;
averageGrade :: (Num a, Eq a) => [a] -> [a] -> a
averageGrade a b | a == [] = 0
| b == [] = 0
| otherwise = sum $ zipWith (*) a b
*Main> averageGrade [0.75 , 0.25] [6, 4]
5.5
然而,正如@chi 提到的,您实际上并不需要检查空列表,因此我们实际上并不需要类型签名中的 Eq
约束。以下应该足够了。
averageGrade :: Num a => [a] -> [a] -> a
averageGrade a b = sum $ zipWith (*) a b
*Main> averageGrade [0.75 , 0.25] [6, 4]
5.5
替代实施:
averageGrade :: [Float] -> [Float] -> Float
averageGrade [] _ = 0
averageGrade _ [] = 0
averageGrade (x:xs) (y:ys) = x * y + (averageGrade xs ys)
用法:
averageGrade [1.0, 2.0] [2.0, 2.0]
我想总结一个压缩列表。
averageGrade :: [Float] -> [Int] -> Float
averageGrade [0.75 , 0.25] [6, 4] , result: 0,75*6 + 0.25*4 = 5.5
当我进入 ghci 并执行以下操作时:
sum(zipWith (*) [0.75, 0.25] [6, 4])
我得到了我想要的。
但是在代码中我遇到了一个错误,我不知道为什么。
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b
| a == [] = 0
| b == [] = 0
| otherwise = (sum(zipWith (*) a b))
如果我想编译它,我会遇到以下失败:
Couldn't match type ‘Int’ with ‘Float’
Expected type: [Float]
Actual type: [Int]
In the third argument of ‘zipWith’, namely ‘b’
In the first argument of ‘sum’, namely ‘(zipWith (*) a b)’
Failed, modules loaded: none.
您不能 *
两个具有不同类型的数字,例如 Float
和 Int
。您需要显式转换其中之一,以便它们具有相同的类型(Float
,在您的情况下)。
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b
| a == [] = 0
| b == [] = 0
| otherwise = sum (zipWith (\ x y -> x * fromIntegral y) a b)
请注意,您实际上不需要检查 ==[]
个案例,因为 zipWith
returns []
是这些案例,而 sum [] == 0
.
averageGrade :: [Float] -> [Int] -> Float
averageGrade a b = sum (zipWith (\ x y -> x * fromIntegral y) a b)
您可以 (*)
不同的类型,因为它们是 Num
类型 class 的成员。您可以向类型签名添加 Num
和 Eq
约束,例如;
averageGrade :: (Num a, Eq a) => [a] -> [a] -> a
averageGrade a b | a == [] = 0
| b == [] = 0
| otherwise = sum $ zipWith (*) a b
*Main> averageGrade [0.75 , 0.25] [6, 4]
5.5
然而,正如@chi 提到的,您实际上并不需要检查空列表,因此我们实际上并不需要类型签名中的 Eq
约束。以下应该足够了。
averageGrade :: Num a => [a] -> [a] -> a
averageGrade a b = sum $ zipWith (*) a b
*Main> averageGrade [0.75 , 0.25] [6, 4]
5.5
替代实施:
averageGrade :: [Float] -> [Float] -> Float
averageGrade [] _ = 0
averageGrade _ [] = 0
averageGrade (x:xs) (y:ys) = x * y + (averageGrade xs ys)
用法:
averageGrade [1.0, 2.0] [2.0, 2.0]