我在编写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
但我看不出任何错误。我做错了什么?
答案 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
但我不知道你是否希望这种行为。