Reputation: 674
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
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