0

The following code represents a function which takes a list as an input and then combines subsequent repetitions of the same value into a sublist. for example : pack ['a','a','b','b','b','a'] = [['a','a'], ['b','b','b'], ['a']]

 pack :: [Char] -> [[Char]]
 pack (x:xs) = ys : pack zs
     where
        (ys, zs) = takeall x (x:xs)
         takeall _ [] = ([], [])
         takeall x (y:ys)
         | x == y = let (us, vs) = takeall x ys
                                  in (y:us, vs)
         
         | otherwise = ([], (y:ys)) 

I found this code in sample solution. I'm still a beginner at haskell but i've seen the similar problem once as an example for an algorithm in C language.while solving this problem it came to my mind to write the code with the help of higher order functions.I thought the combination of foldl,filter and concatMap could be a good solution for this problem, however i'm not quite sure about filter.I wanted to write a function for filter which goes through the list and compares each element with it's neighbour elements and if they are eqaul returns true. Writing a function like that could be easy but how should i combine it with other functions of higher order so the things that are true come to a list together? How do you solve this problem with higher order functions?

1
  • You can use zip with the list and its tail and then filter on the 2-tuples. Commented May 26, 2022 at 15:26

1 Answer 1

1

Firstly, your takeall function can be replaced with the span function from Prelude:

pack :: [Char] -> [[Char]]
pack (x : xs) = ys : pack zs
  where
    (ys, zs) = span (== x) (x : xs)
pack [] = []

Then, you can get rid of the explicit recursion using unfoldr:

import Data.List (unfoldr)

pack2 :: [Char] -> [[Char]]
pack2 = unfoldr go
  where
    go (x : xs) = Just $ span (== x) (x : xs)
    go [] = Nothing
main :: IO ()
main = do
  print $ pack ['a', 'a', 'b', 'b', 'b', 'a']
  print $ pack2 ['a', 'a', 'b', 'b', 'b', 'a']

Output:

["aa","bbb","a"]
["aa","bbb","a"]
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.