2014-01-15 41 views
2

編寫Haskell函數時出現問題。編譯器說:在應用Haskell - 應用程序中的類型錯誤

類型錯誤

表達:移動(偏移 - 1)(saveList子列表(X:XS))XS

test :: Int -> [Int] -> [Int] 
test _ [] = [] 
test offset (xs) = move offset [] xs 
        where 
         move offset subList (x:xs) | offset == 0 = subList ++ rotate (last (x:xs)) (x:xs) 
                | otherwise = move (offset-1) (saveList subList (x:xs)) xs 

         saveList save (x:xs) = save ++ [x] 

         rotate _ [] = [] 
         rotate item (x:xs) = item : (move x xs) 

         last (x:[]) = x 
         last (x:xs) = last xs 

但我不能看到任何錯誤。我做錯了什麼?

回答

5

它看起來像move應該是三個參數的函數,但在rotate中,您可以像這樣使用它:item : (move x xs)

在Haskell,move x xs是一個有效的值(它是由柯里move兩次獲得的功能,先用x,然後用xs),但它似乎並不像你想要的這裏。

當您收到一個令人困惑的錯誤消息時,通過添加類型簽名來澄清您對編譯器的含義通常很有幫助。我添加類型簽名您這樣的代碼:

move :: Int -> [Int] -> [Int] -> [Int] 
saveList :: [Int] -> [Int] -> [Int] 
rotate :: Int -> [Int] -> [Int] 
last :: [Int] -> Int 

GHCI然後給了我下面的錯誤消息,這大約是實際的問題出在哪裏大有幫助:

foo.hs:14:52: 
    Couldn't match expected type `[Int]' 
      against inferred type `[Int] -> [Int]' 
    In the second argument of `(:)', namely `(move x xs)' 
    In the expression: item : (move x xs) 
    In the definition of `rotate': 
     rotate item (x : xs) = item : (move x xs) 

此錯誤消息表示相當顯然,在第14行閱讀(move x xs)時,GHCI預計會發現[Int](整數列表)類型,但實際上發現了[Int] -> [Int](取整數列表並返回整數列表的函數)類型的東西。

+0

好的坦克你。我是否也可以將類型簽名添加到where子句中的函數中? – Cilenco

+0

@Cilenco是的,你可以,只需在功能相同的縮進級別添加類型簽名。 – svk

1

首先,函數last已經存在於Prelude中,所以你不需要自己定義它。其次,請使用空格而不是製表符。這是本週我第五次在SO上這樣說過。 Haskell將與製表符一起工作,但它最終會導致問題,因爲在編輯器塊中查看排隊,但解析器並不總是這樣看。它還會在複製/粘貼到計算器時混亂格式。

,我發現這個問題實際上是在定義rotate

rotate item (x:xs) = item : move x xs 

在這裏,你只提供2 3的參數move,所以你得到一個類型錯誤。我得到它與編譯

rotate item (x:xs) = item : move x [] xs 

但我不知道你是否是你想要的行爲。