Haskell - 应用程序中的类型错误

时间:2014-01-15 14:40:18

标签: haskell

我在编写Haskell函数时遇到问题。编译器说:

  

在应用程序中输入错误

     

表达式:move(offset - 1)(saveList subList(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

但我看不出任何错误。我做错了什么?

2 个答案:

答案 0 :(得分: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]类型的某些内容(整数列表),但实际上找到了{{1}类型的内容(一个函数获取整数列表并返回一个整数列表)。

答案 1 :(得分:1)

首先,last中已存在函数Prelude,因此您无需自行定义。其次,请使用空格而不是制表符。这是我本周第五次在SO上说过这个。 Haskell将使用选项卡,但它最终会导致问题,因为在您的编辑器块中看起来排成一行,但解析器并不总是这样看。当您复制/粘贴到stackoverflow时,它也会混乱格式化。

我发现的问题实际上在rotate的定义中:

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

在这里,您只向move提供3个参数中的2个,因此您会收到类型错误。我用

编译了它
rotate item (x:xs) = item : move x [] xs

但我不知道你是否希望这种行为。