0

I've just started Haskell and after reading Foldable documentation I'm trying to Define an instance of the constructor class Foldable for the constructor ListBag where : newtype ListBag a = LB [(a,Int)] deriving (Show,Eq)

To this aim, I have binary function f that applies to first elements of my multiset. and this is what I have tried:

instance Foldable ListBag where
  foldr f z (LB[]) = 0 
  foldr f z (LB [x]) = f i z where (i,_) = x
  foldr f z (LB [x : xs]) = f i foldr f z (LB[xs]) where (i,_) = x

which is not correct but best I could do...

any idea how to correct it?

(Yes, the f function should be applied ignoring multiplicities.)

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • Is a value `LB [(x,2), (y,3)]` meant to represent two `x` and three `y`? Is so, you need to produce `f x (f x (f y (f y (f y z))))`. You can't pass integers to `f`, nor return integers from `foldr`, as you are trying to do right now. – chi Jan 23 '21 at 19:50
  • 1
    @chi They're not passing integers to `f`, even after correcting their pattern matching. – Daniel Wagner Jan 23 '21 at 19:53
  • @chi thanks for your time, yes it was how ```LB``` created but at the moment I want to apply f to first elements _ignoring the multiplicities_ . – mohammad farhady Jan 23 '21 at 19:56
  • I see. Given `list :: [(a,Int)]` we have `map fst list :: [a]`, so you could apply the `foldr` for the standard lists to that. If you want to instead fix your approach, don't use `LB [x]` or `LB [x:xs]` for your patterns. To match a non-empty list, you need `LB (x:xs)` instead, or `LB ((x,_):xs)` to get only the first component. – chi Jan 23 '21 at 20:03
  • @DanielWagner Ah, right. I was confused by the name `i`, which I thought to be the `Int` component. – chi Jan 23 '21 at 20:04

1 Answers1

2

The pattern [x] matches a list with one element, just like you were hoping. But the pattern [x : xs] also matches a list with one element -- that must itself be a list, and non-empty. You want (x : xs) instead. (Similarly, in that line, you want LB xs, not LB [xs], as the latter attempts to wrap an extra layer of lists around the tail of the list.)

Additionally, I suspect you will be happier with an instance that, when it sees (i,v), pretends there are v copies of i, rather than always incorporating i exactly once.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • thank you Daniel, that really helped. I've edited the code based on what you and @chi said. dose it seems right to you now? – mohammad farhady Jan 23 '21 at 20:20
  • @mohammadfarhady Yes, that looks fine. However, please don't make that kind of edit in the future (I've rolled it back). The goal of StackOverflow is to serve as an archival collection of questions and their answers -- so dramatically changing the content of a question after it is answered isn't good form. If you have additional problems, you can open a new question, describing the next roadblock you are facing. – Daniel Wagner Jan 23 '21 at 20:26