Reputation: 29
I'm trying to write a function which would split a list into few separate lists on the instance of one specific integer. Example:
splitlist [3, 4, 0, 6, 0, 7] 0
would return [[3, 4], [6], [7]]
So far I've got:
splitlist :: [Int] -> Int -> [[Int]]
splitlist xs n
| length xs == 0 = []
| head xs == n = [head (tail xs)] : splitlist (tail xs) n
| otherwise = [head xs : splitlist (tail xs) n]
However, I'm getting a type error for head xs
in line 5:
• Couldn't match type ‘[Int]’ with ‘Int’
Expected type: [Int]
Actual type: [[Int]]
• In the second argument of ‘(:)’, namely ‘splitlist (tail xs) n’
In the expression: head xs : splitlist (tail xs) n
In the expression: [head xs : splitlist (tail xs) n]
|
5 | | otherwise = [head xs : splitlist (tail xs) n]
| ^^^^^^^^^^^^^^^^^^^^^
What am I doing wrong?
Upvotes: 0
Views: 132
Reputation: 48572
xs
has type [Int]
, so head xs
has type Int
. splitlist
has type [Int] -> Int -> [[Int]]
, so splitlist (tail xs) n
has type [[Int]]
. You're trying to call :
on those values, which has type a -> [a] -> [a]
. The problem is that no choice of a
makes that work out: if you pick Int
for a
, then it's wrong because the second parameter is [[Int]]
rather than [Int]
, and if you pick [Int]
for a
, then it's wrong because the first parameter is Int
rather than [Int]
.
I think you meant to write [head xs] : splitlist (tail xs) n
instead of [head xs : splitlist (tail xs) n]
, like in the line above that one. However, although this type-checks, it still doesn't work (it produces [[3],[4],[6],[6],[7],[7]]
on your test case, and splitlist [0] 0
bottoms).
To actually fix it, let's first rewrite it to look a bit more idiomatic:
splitlist :: [Int] -> Int -> [[Int]]
splitlist [] _ = []
splitlist (x:xs) n
| x == n = [head xs] : splitlist xs n
| otherwise = [x] : splitlist xs n
The change I made is that I used pattern-matching in place of testing length
and then using head
and tail
. Now the problems with the logic become apparent:
Int
in the output for each Int
in the inputI assume this is some sort of exercise, so I'm not going to spoil the final answer. However, this should be enough to get you going again.
Upvotes: 1