Search code examples
listhaskellmonoids

Add a list to a list of lists in Haskell


How can I add a list to a list of lists? Say I want to add itemz to bagList, which is a list of lists. How can I do that?

bagList itemz = mappend bagList itemz               

Solution

  • You might want to consider adding it at the front, this is faster:

    bagItem bag item = item : bag
    

    Also it looks like you're coming from an imperative mindset, the way you use bagList before and after the = is not quite right: the expressions before and after the = do not really represent the same construction. Before the = bagItem is used as a function, after the = it's used as some Monoid (which if itemz is a list would also need to be a list).

    If you really do want to append the item (this will be slower, because the operation will require going all the way through the list to add the new item at the end, and the whole list will need to be reconstructed) you can do what Christoph suggests or you can go for a recursive formulation something like this:

    appendItem :: a -> [a] -> [a]
    appendItem i (x:xs) = x : appendItem i xs
    appendItem i [] = i : []
    

    If you both want to append and are also worried about performance, you should have a look at difference lists, for example look for the section on difference lists in this chapter in Learn You a Haskell.


    Update

    From the comments it seems what you are actually looking for is Maps. We can make a Map with each item as a key, and the number of occurrences as the value. In your case it seems this will be a Map String Int.

    import Data.List (foldl')
    import qualified Data.Map as M
    
    bag :: M.Map String Int
    bag = M.empty
    
    addToBag :: M.Map String Int -> [String] -> M.Map String Int
    addToBag = foldl' go
      where go m i = M.insertWith (+) i 1 m
    
    main = print $ addToBag bag ["a","b","c","a"]
    -- fromList [("a",2), ("b", 1), ("c", 1)]