hug*_*vey 0 haskell types functional-programming fold
我正在尝试编写一个函数来计算2个列表的内积,即如果列表是[1,2,3]和[4,5,6]那么内积将是(1 x 4)+(2 x 5)+(3 x 6)= 4 + 10 + 18 = 32.
所以我想用来zipWith获取产品,然后再foldl添加它们.所以zipWith应该产生[4,10,18],然后将foldl它加到32.
所以我写了:
innerprod [] [] = 0
innerprod x y = foldl (+) 0 (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)
一切都编译但是当我在ghci中运行时:
Prelude ListFuncs> innerprod [1,2,3] [4,5,6]
<interactive>:3:1:
No instance for (Num
([c0] -> (a0 -> b0 -> a0) -> a0 -> [b0] -> a0))
arising from a use of `innerprod'
Possible fix:
add an instance declaration for
(Num ([c0] -> (a0 -> b0 -> a0) -> a0 -> [b0] -> a0))
In the expression: innerprod [1, 2, 3] [4, 5, 6]
In an equation for `it': it = innerprod [1, 2, 3] [4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
由于错误消息,我尝试制作这样的代码,但它在编译时返回一个不同的错误:
innerprod :: Num [Int] => (Int -> Int -> Int) -> Int -> [Int] -> Int
innerprod [] [] = 0
innerprod x y = foldl + 0 (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)
有谁知道什么是错的?我会有签名,innerprod :: [Int] -> [Int] -> Int因为它需要2个int列表并返回一个int.但这也不起作用.感谢您的时间.如果我不应该在这里问这个问题,请告诉我.
lef*_*out 10
Num [Int] => (Int -> Int -> Int) -> Int -> [Int] -> Int是一个完整的虚假签名.这意味着:"如果任何整数列表都可以被视为一个数字[??!],我会给你一个特殊版本的折叠".这不像你想要的内在产品,即Vector -> Vector -> Scalar; 在这种情况下Num a => [a] -> [a] -> a.事实上,通过该签名,您的原始定义可以完美地运行:
innerProd :: Num a => [a] -> [a] -> a
innerProd x y = foldl' (+) 0 (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)
ListFuncs*> innerProd [1,2,3] [4,5,6]
32
我想你还没有尝试过这个.你写的是没有parens周围+.
foldl + 0 (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)
现在,那是另一头野兽.这意味着,你foldl通过将0函数应用到列表的zip 来将函数添加到你得到的函数中......另一个明显的伪造的东西.请记住,中缀运算符与正常函数应用程序绑定不同,您需要将它们打包在parens中以将它们作为函数参数传递.