2013-09-25 23 views
3

我是一个试图学习哈斯克尔的新手,我试图寻找类似的东西在其他论坛,但无法找到类似的问题。哈希克尔currying删除参数变量在最后

addPoly :: (Num a)=>[[a]]->[a] 
addPoly x = map sum $ transpose x 

运行正常

,但是当我在最后它的错误删除X出来

addPoly :: (Num a)=>[[a]]->[a] 
addPoly = map sum $ transpose 

错误说:

Couldn't match expected type `[[Integer]] -> [Integer]' 
      with actual type `[Integer]' 
In the expression: map sum $ transpose 
In an equation for `addPoly': addPoly = map sum $ transpose 

Couldn't match expected type `[[Integer]]' 
      with actual type `[[a0]] -> [[a0]]' 
In the second argument of `($)', namely `transpose' 
In the expression: map sum $ transpose 
In an equation for `addPoly': addPoly = map sum $ transpose 

无法弄清楚,我错过了什么这里。

免责声明:这不是一门功课问题

回答

7

$是在Haskell定义为

f $ x = f x 
infixr 0 $ 

权所以,如果你扩大你的代码的第一个片段,

map sum $ transpose x 

变成

map sum (transpose x) 

这将工作。

但第二个片段

map sum $ transpose 

成为

​​

,当你调用与x,你

map sum transpose x 

这实际上地图的sum超过transpose(并调用结果与参数x,这也没有意义,并且会导致出现错误消息,因为map将返回List,而不是函数),而不是transpose x

您需要使用这个.功能,而不是$,它被定义为

(.) f g = \x -> f (g x) 

如果你这样做,你的代码

map sum . transpose 

成为

\x -> map sum (transpose x) 

,当你从一些参数x,它只是变成了

map sum (transpose x) 

这是我们开始使用的(正确的)代码。

让我知道如果有什么不清楚。

+0

我会补充一点,在删除参数时的一般经验法则是将'$'s改为'.'s。显然,这在每种情况下都不起作用,但对于模式'f x = g1 $ g2 $ g3 $ g4 x',您可以将其重写为'f = g1。 g2。 g3。 g4' – bheklilr

1

正确的代码是:

addPoly :: (Num a)=>[[a]]->[a] 
addPoly = map sum . transpose 

如何在它到达?请记住以下两个规则:

f $ x = f x 
f. g $ x == (f.g) x == f (g x) == f $ g x 

因此,

addPoly x = map sum $ transpose x 

被改写为

addPoly x = map sum $ transpose $ x 

,然后将每个$但最后由.所取代。

addPoly x = map sum . transpose $ x 

现在,因为你只有一次$和参数仅是在$您可以切换到自由点式