in-haskell类型匹配错误

in-haskell类型匹配错误,haskell,Haskell,我正在使用hugs编译一个简单的Haskell函数。但是我的函数有类型错误 这就是功能: expression :: Int -> Int -> Int expression n d = countN d 0 0 (div n 2) countN :: Int->Int->Int->Int->Int countN goal now max left = if(left == 0 && max == goal) then 1 else if

我正在使用hugs编译一个简单的Haskell函数。但是我的函数有类型错误 这就是功能:

expression :: Int -> Int -> Int
expression n d  = countN d 0 0 (div n 2)

countN :: Int->Int->Int->Int->Int
countN goal now max left 
=
if(left == 0 && max == goal) then 1
else if(left == 0) then 0
else if(max > goal || now>left) then 0
else if(now == 0) then countN(goal now+1 (if(now+1>max) then now+1 else max) left)
else countN(goal now+1 (if(now+1>max) then now+1 else max) left) + countN(goal now-1 max left-1)
这是一个错误:

 Type error in application
 *** Expression     : goal now
 *** Term           : goal
 *** Type           : Int
 *** Does not match : a -> b

问题在于这部分代码

countN(goal now-1 max left-1)
哈斯克尔将此解释为

countN ((goal now) - (1 (max left)) - 1)
。。。这显然不是你的意思,但haskell看到你试图调用
goal
,参数为
now
goal
的类型是
Int
,但您试图对其应用参数,从而将其视为
a->b
,因此出现类型错误

请记住whitspace是函数应用程序,运算符的优先级高于函数应用程序,也许您的意思是:

countN goal (now-1) max (left-1)
这将使您的最终表达如下:

(countN goal (now+1) next left) + (countN goal (now-1) max (left-1))
    where next = if now+1 > max then now+1 else max

有两件事:1)用GHC代替拥抱。Hugs已经被弃用了好几年了,它还没有进行任何更新,而GHC非常活跃。您还将获得更多信息性错误消息(即使它们一开始看起来更复杂)。2) 在选项卡上使用空格。从技术上讲,您可以在Haskell source中使用制表符,但我看到人们总是因为制表符而在这里发布语法错误的问题。3) 最重要的是,在这里使用保护,而不是嵌套if-then-else语句。这将导致更干净的代码。4) 所有这些括号,你不需要它们!此外,由于括号的原因,您似乎有很多分组问题。Haskell在函数应用程序中不使用parens,只用于分组操作,因此类似于
countN(goal now+1..)
的内容告诉编译器
goal
是一个函数,它接受参数
now
并返回一个
Int
,该值递增1,然后,它应该是一个函数,该函数将参数
if(now+1>max然后now+1 else max)作为其单个参数传递给函数
countN
。这个错误是由于语法错误造成的,仅此而已。我想你真的更喜欢这样的东西。我不确定这是否是您想要的实现,但它肯定更具可读性,不会覆盖内置的
max
函数(在本例中,该函数非常有用,用于替换内嵌的if语句),并通过删除所有导致您出问题的额外参数,使它看起来不像lisp。