Reputation: 7179
I have a problem writing a Haskell function. The compiler says:
Type error in application
Expression : 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
But I can't see any mistake. What did I do wrong?
Upvotes: 2
Views: 475
Reputation: 5919
It looks like move
is supposed to be a function of three arguments, but in rotate
you use it like this: item : (move x xs)
.
In Haskell, move x xs
is a valid value (it's the function obtained by currying move
twice, first with x
and then with xs
), but it doesn't seem like what you want here.
When you get a confusing error message, it often helps to clarify what you mean to the compiler by adding type signatures. I added type signatures to your code like this:
move :: Int -> [Int] -> [Int] -> [Int]
saveList :: [Int] -> [Int] -> [Int]
rotate :: Int -> [Int] -> [Int]
last :: [Int] -> Int
GHCI then gives me the following error message, which is much more helpful about where the actual problem is:
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)
This error message says quite plainly that when reading (move x xs)
on line 14, GHCI expected to find something of type [Int]
(a list of integers), but actually found something of type [Int] -> [Int]
(a function taking a list of integers and returning a list of integers).
Upvotes: 5
Reputation: 54078
First of all, the function last
exists already in Prelude
, so you don't need to define it yourself. Secondly, please use spaces instead of tabs. This is about the 5th time I've said this on SO this week. Haskell will work with tabs, but it ends up causing problems because in your editor blocks look lined up, but the parser doesn't always see it that way. It also messes up formatting when you copy/paste into stackoverflow.
The problem I found was actually in the definition for rotate
:
rotate item (x:xs) = item : move x xs
Here, you're only providing 2 of 3 arguments to move
, so you're getting a type error. I got it to compile with
rotate item (x:xs) = item : move x [] xs
But I don't know if that you're desired behavior.
Upvotes: 1