2014-10-03 43 views
3

我是Haskell的新手,我的代碼不會編譯。編寫我的第一個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行,第2個出現在第6行。我做錯了什麼? (該功能應該是3的倍數和5以下n個總和)

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 

回答

8

您有兩個與語法有關的問題。第一個與函數和運算符優先級有關。函數應用程序在Haskell中的優先級最高,所以recSum a-1 b+a被視爲與(recSum a)-(1 b)+a相同。相反,您需要編寫recSum (a-1) (b+a)

第二個問題是a mod 3是函數a調用參數mod3。要使用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 
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的錯誤。

OK,好,我有寫反引號與綴功能,所以這應該是

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 

現在,它的編制,它的時間有各種測試一下看看它是否能達到預期的效果。