Vlad Balanescu
Vlad Balanescu

Reputation: 674

Map a list into a type

I am trying to transform a list ["a","b","c","c"] into a set in haskell, say: [("a",1),("b",1),("c",2)]. I am not trying to use maps. My function looks like so:

-- bagMyItem
bagMyItem :: Eq g => [g] -> Bag g -> Bag g
bagMyItem  (h:t) bag
     | h==q = (q,v+1):(listToBag t bag)  
     | null rBag = bag ++ [(h,1)]     
     | otherwise = (q,v):(listToBag (h:t) rBag)
     where ((q,v):rBag) = bag

Am I doing something wrong, or am I missing any case in this?

Upvotes: 0

Views: 89

Answers (1)

ErikR
ErikR

Reputation: 52049

Here are my suggestions for how to solve this:

Step 1: Initially I would write the functions with concrete types. When you make mistakes you'll get less cryptic error messages. Later you can go back and make the functions polymorphic.

Step 2: Let's choose Char as our concrete type. Write a function which bags a single Char:

type Bag g = [ (g,Int) ]

bagSingleItem :: Char -> Bag Char -> Bag Char
bagSingleItem c [] = ...
bagSingleItem c ( (d,v) : bag ) = ...

Step 3: Use this function to write one which bags a whole list of items:

bagItems :: [Char] -> Bag Char -> Bag Char
bagItems [] bag = ...
bagItems (c:cs) bag =  ... bagSingleItem ...

Step 4. Make your functions polymorphic. All you need to do is to change the type signatures of bagSingleItem and bagItems by replacing Char with a type variable and add the Eq ... constraint:

bagSingleItem :: Eq g => g -> Bag g -> Bag g
(definition remains the same)

bagItems :: Eq g => [g] -> Bag g -> Bag g
(definition remains the same)

Or - even better - remove the type signatures completely and have ghci tell you what they are with the :t command:

ghci> :t bagSingleItem
...
ghci> :t bagItems
...

Upvotes: 1

Related Questions