我是Haskell的新手,我的代码不会编译。
multipleSum :: Int -> Int
multipleSum x = let recSum 0 b = b
recSum a b | a mod 3 == 0 = recSum a-1 b+a
| a mod 5 == 0 = recSum a-1 b+a
| otherwise = recSum a-1 b
in recSum x 0
这是我得到的两个错误,第一个出现在第3行,第二个出现在第6行。我做错了什么? (该函数应该是n以下3和5的所有倍数之和)
1.
Occurs check: cannot construct the infinite type: a ~ a -> a -> a
Expected type: (a -> a -> a) -> a -> a
Actual type: ((a -> a -> a) -> a -> a) -> (a -> a -> a) -> a -> a
Relevant bindings include
b :: (a -> a -> a) -> a -> a
(bound at src\Main.hs:5:30)
a :: (a -> a -> a) -> a -> a
(bound at src\Main.hs:5:28)
recSum :: ((a -> a -> a) -> a -> a)
-> ((a -> a -> a) -> a -> a) -> (a -> a -> a) -> a -> a
(bound at src\Main.hs:4:21)
In the first argument of `(-)', namely `recSum a'
In the first argument of `(+)', namely `recSum a - 1 b'
2.Couldn't match expected type `(a0 -> a0 -> a0) -> a0 -> a0'
with actual type `Int'
In the first argument of `recSum', namely `x'
In the expression: recSum x 0
Couldn't match expected type `Int'
with actual type `(a0 -> a0 -> a0) -> a0 -> a0'
Probable cause: `recSum' is applied to too few arguments
In the expression: recSum x 0
In the expression:
let
recSum 0 b = b
recSum a b
| a mod 3 == 0 = recSum a - 1 b + a
| a mod 5 == 0 = recSum a - 1 b + a
| otherwise = recSum a - 1 b
in recSum x 0
答案 0 :(得分:8)
您有两个与语法相关的问题。第一个与函数和运算符优先级有关。函数应用程序在Haskell中具有最高优先级,因此recSum a-1 b+a
被视为与(recSum a)-(1 b)+a
相同。相反,你需要写recSum (a-1) (b+a)
。
第二个问题是a mod 3
是使用参数a
和mod
调用的函数3
。要将mod
用作infix operator,请将其写为
a `mod` 3
将这两个变化放在一起我们
multipleSum :: Int -> Int
multipleSum x = let recSum 0 b = b
recSum a b | a `mod` 3 == 0 = recSum (a-1) (b+a)
| a `mod` 5 == 0 = recSum (a-1) (b+a)
| otherwise = recSum (a-1) b
in recSum x 0
答案 1 :(得分:7)
首先,您可以获得的签名类型越多,调试就越容易,因此我将其重写为
multipleSum :: Int -> Int
multipleSum x = recSum x 0
recSum :: Int -> Int -> Int
recSum 0 b = b
recSum a b | a mod 3 == 0 = recSum a-1 b+a
| a mod 5 == 0 = recSum a-1 b+a
| otherwise = recSum a-1 b
然后用ghci或拥抱开火。
这样我收到有关a mod 3
的错误。
好的,我必须用反引号编写中缀函数,所以应该是
recSum :: Int -> Int -> Int
recSum 0 b = b
recSum a b | a `mod` 3 == 0 = recSum a-1 b+a
| a `mod` 5 == 0 = recSum a-1 b+a
| otherwise = recSum a-1 b
现在我在recSum a-1 b+a
中收到有关参数数量的错误。那是因为应该只有两个,所以如果我要传递比单个变量更复杂的东西,我需要括号,所以我应该写
recSum :: Int -> Int -> Int
recSum 0 b = b
recSum a b | a `mod` 3 == 0 = recSum (a-1) (b+a)
| a `mod` 5 == 0 = recSum (a-1) (b+a)
| otherwise = recSum (a-1) b -- don't need brackets for b on its own
现在已经编译好了,现在是时候用各种输入来测试它,看看它是否符合它的预期。