Reputation: 1072
bundle :: Int -> [a] -> [[a]]
bundle 0 _ = []
bundle n (x:xs) = [x:bundle (n-1) xs]
My goal is to do something like this
bundle 3 [1,2,3,4,5] = [[1,2,3]]
The code is giving me the error
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for bundle :: Int -> [a] -> [[a]]
Upvotes: 1
Views: 214
Reputation: 116139
bundle :: Int -> [a] -> [[a]]
bundle 0 _ = []
bundle n (x:xs) = [x:bundle (n-1) xs]
bundle (n-1) xs
has type [[a]]
. For x : bundle (n-1) xs
to make sense, x
must be an element of [[a]]
, so it must be an [a]
. But it is simply an a
.
In other words, you are attempting to build an ill-formed list such as
[ 1 , [2,3] , [4,5] ]
^-- not a list
Do you really want to build a [[a]]
? Isn't an [a]
more appropriate for your goal?
Upvotes: 3
Reputation: 52280
Chi wrote a bit about the problem - I start at your example and see where it leads me.
I honestly don't understand why you want the second warping but the easiest way you can get this going would be:
bundle :: Int -> [a] -> [[a]]
bundle 0 _ = [[]]
bundle n (x:xs) = let [xs'] = bundle (n-1) xs in [x : xs']
of course this will give you [[]]
for ´bundle 0 ...` but I think that's indeed what you want
Now of course there are some easier ways - for example there is already a function that does something similar: take
- it just does not wrap the second time but this you can do with a simple return
:
bundle :: Int -> [a] -> [[a]]
bundle n = return . take n
Upvotes: 1