
I just started learning haskell and I just came to my first wtf moment. I'm trying to do something like this: calling: foo 3 [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns: [[1,2,3],[2,4,1,6,3],[2,3]] but i have no idea how to put something into a sublist. How to make a list of sublists out of a list, whether they be a list of numbers or a string. TX in advance. -- View this message in context: http://www.nabble.com/list--%3E-sublists-tp25975341p25975341.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

2009/10/20 satorisanitarium
I just started learning haskell and I just came to my first wtf moment.
I'm trying to do something like this:
calling: foo 3 [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4]
returns: [[1,2,3],[2,4,1,6,3],[2,3]]
but i have no idea how to put something into a sublist.
How to make a list of sublists out of a list, whether they be a list of numbers or a string.
Hi, Here is a function f that looks like a recursive implementation of the function length. f is the identity for lists but shows clearly how you can build the list again. ghci> let f [] = [] ; f (x:xs) = x : f xs ghci> f "hello" "hello" But here is what happen if we change it slightly so that each element is turned into a list (which is still viewed as an element from the point of view of the enclosing list). ghci> let f [] = [] ; f (x:xs) = [x] : f xs ghci> f "hello" ["h","e","l","l","o"] If it's not clear, try to write down the type of each version of f. Now back to your original problem. Can you write a function g such that g [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns ([1,2,3],[2,4,1,6,3,6,2,3,5,2,5,2,1,6,4]) g [2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns: ([2,4,1,6,3],[6,2,3,5,2,5,2,1,6,4]) and so on ? Then you should be able to build what you wanted by using g in a modified version of f. Yell if something doesn't make sense. Cheers, Thu

Now back to your original problem. Can you write a function g such that g [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns ([1,2,3],[2,4,1,6,3,6,2,3,5,2,5,2,1,6,4])
I know the diference between x and [x], my problem lies in going from [1,2,3,4,5,6,7] to [[1,2,3,4],[5,6,7]], I don't know how to write code that would group some elements together.

On Tue, Oct 20, 2009 at 9:27 AM, satorisanitarium
Now back to your original problem. Can you write a function g such that g [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns ([1,2,3],[2,4,1,6,3,6,2,3,5,2,5,2,1,6,4])
I know the diference between x and [x], my problem lies in going from [1,2,3,4,5,6,7] to [[1,2,3,4],[5,6,7]], I don't know how to write code that would group some elements together.
Here is an implementation of splitAt from the prelude (though it is not hte implementation given in the prelude) for guidance. For example, splitAt 3 ['a','b','c','d','e','f'] = (['a','b','c'],['d','e','f']) splitAt :: Int -> [a] -> ([a],[a]) splitAt 0 xs = ([], xs) splitAt n [] = ([],[]) splitAt n (x:xs) = let (rfst, rsnd) = splitAt (n-1) xs in (x:rfst, rsnd) See if you can use that pattern to make the function that splits at a particular element (as opposed to index). Luke

Now back to your original problem. Can you write a function g such that g [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns ([1,2,3],[2,4,1,6,3,6,2,3,5,2,5,2,1,6,4])
g [2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] returns: ([2,4,1,6,3],[6,2,3,5,2,5,2,1,6,4])
and so on ? Then you should be able to build what you wanted by using g in a modified version of f.
For this kind of questions, Hoogle[1] is your friend. You have a list of type [a], and you want to split it into a pair of (the list up to some point, the rest of the list), whose type is then ([a],[a]). So you search in Hoogle: [a] -> ([a],[a]) and the following results come up: Prelude.break :: (a -> Bool) -> [a] -> ([a], [a]) Prelude.span :: (a -> Bool) -> [a] -> ([a], [a]) (... a few more...) A quick review of the descriptions will show that one of these functions is /very/ close to what you want to achieve. You may use it to implement your solution and/or look at its source code to understand how it works. In fact, you can do better---look at your /original/ problem and figure out what type to search for in Hoogle. One of the results there should turn your problem into a one-liner. Again, you can take a look at its code for additional insight. References: [1] http://www.haskell.org/hoogle/ Have fun! -- Ariel J. Birnbaum

On Oct 21, 2009, at 3:16 AM, satorisanitarium wrote:
I just started learning haskell and I just came to my first wtf moment.
I'm trying to do something like this:
calling: foo 3 [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4]
returns: [[1,2,3],[2,4,1,6,3],[2,3]]
but i have no idea how to put something into a sublist.
From the way you talk about the problem, I suspect that you are trying to understand in a rather complicated way. Here's how I approach your example: foo item list = if there is an occurrence of item in list then a new list whose first element is everything up to and including that occurrence and whose remaining elements are found by applying foo item to everything after that occurrence else an empty list We can do this in just a couple of lines using List.elemIndex and splitAt, but let's do it in an elementary way. We'll write a helper function that either returns (before-and-including-item, after-item) or nothing. find_and_split :: Eq t => t -> [t] -> Maybe ([t], [t]) find_and_split item list = loop list [] where loop [] _ = Nothing loop (x:xs) before | x == item = Just (reverse (x:before), xs) loop (x:xs) before = loop xs (x:before) foo :: Eq t => t -> [t] -> [[t]] foo item list = case find_and_split item list of Nothing -> [] Just (before, after) -> before : foo item after The answer I get is *Main> foo 3 [1,2,3,2,4,1,6,3,6,2,3,5,2,5,2,1,6,4] [[1,2,3],[2,4,1,6,3],[6,2,3]] ^ which differs from yours at the marked place, but which I think is right. List.elemIndex tells you where an element occurs. Just 0 is the first position. splitAt splits a list into two pieces, the size argument tells you the length of the first piece. So foo item list = case List.elemIndex item list of Nothing -> [] Just pos -> before : foo item after where (before, after) = splitAt (pos+1) list This gives the same answer as the previous version. In neither case do we do ANYTHING to "put" items into a "sublist", we just construct a list whose elements happen to be lists. It's no different from calculating a list of numbers.

satorisanitarium wrote:
How to make a list of sublists out of a list, whether they be a list of numbers or a string.
Without recursion (with fold) starting from the tail of the input list: foo n = foldr st [[]] where st x xss | x == n = [x]:xss st x (xs:xss) = (x:xs):xss -- View this message in context: http://www.nabble.com/list--%3E-sublists-tp25975341p25998649.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
participants (6)
-
Ariel J. Birnbaum
-
Eduard Sergeev
-
Luke Palmer
-
minh thu
-
Richard O'Keefe
-
satorisanitarium