||
||	for jwj, based on my own earlier bags implementation mixed in with
||	some functions from a Miranda past paper question
||

bag * == [(*,num)]

empty :: bag *
  empty = []

isempty :: bag * -> bool
  isempty b = b=[]

add :: * -> bag * -> bag *
  add x [] = [(x,1)]
  add x ((e,numb):t) = (e,numb+1):t, if x=e
                     = (e,numb):add x t, otherwise

remove :: bag * -> (*, bag *)
  remove [] = error "nothing in bag"
  remove ((e,numb):t) = (e, t), if numb=1
                      = (e, (e,numb-1):t), otherwise

delete :: * -> bag * -> bag *
  delete e [] = error "element not in bag"
  delete e ((e',numb):t) = t, if e=e' & numb=1
                         = (e',numb-1):t, if e=e' & numb>1
                         = (e',numb):delete e t, otherwise

union :: bag * -> bag * -> bag *
  union b1 b2 = b2, if isempty b1
              = union b1down1 b2up1, otherwise
                where
                (e,b1down1) = remove b1
                b2up1 = add e b2

union_v2 :: bag * -> bag * -> bag *
  union_v2 []    b2 = b2
  union_v2 (h:t) b2 = union_v2 t (add_several h b2)
                      where
                      add_several (e,numb) [] = [(e,numb)]
                      add_several (e,numb) ((e',numb'):t)
                        = (e',numb+numb'):t, if e=e'
                        = (e',numb'):add_several (e,numb) t, otherwise

union_v3 :: bag * -> bag * -> bag *
	union_v3 []           b2 = b2
	union_v3 ((e,numb):t) b2 = union_v3 t              (add e b2), if numb=1
                                 = union_v3 ((e,numb-1):t) (add e b2), if numb>1

wrong_bagMap :: (* -> **) -> bag * -> bag **
|| wrong because exam question says merge duplicates into a bigger count
	wrong_bagMap f []           = []
	wrong_bagMap f ((e,numb):t) = (f(e), numb) : wrong_bagMap f t

bagMap :: (* -> **) -> bag * -> bag **
	bagMap f []           = []
	bagMap f ((e,numb):t) = add (f(e)) (bagMap f t             ), if numb=1
                              = add (f(e)) (bagMap f ((e,numb-1):t)), if numb>1
