Home > OS >  Pattern match on data types
Pattern match on data types

Time:01-12

I have been struggling with this problem so far and was wondering if someone could point me in the right direction. This is my template so far:

data Expense = MkExpense Double String deriving (Eq,Ord)

mkExpense :: String -> Double -> Expense
mkExpense name amount = MkExpense amount name

instance Show Expense where
  show (MkExpense amount name) = name    ": "    show amount

data Delta = MkDelta Expense deriving (Eq,Ord)

instance Show Delta where
  show (MkDelta (MkExpense amount name)) = name    ": "    show amount

Right now I would like to sum over all the amounts of a list of the form (so in this case I would like to get 240):

[mkExpense "Alex" 40, mkExpense "Gert-Jan" 200]

which returns:

[Alex: 40.0,Gert-Jan: 200.0]

I know of the existence of foldr but I'm not sure how to pattern match properly against the "amounts" here. Normally I would use map to re-map to a single value list so I can use foldr freely, but it's not possible here because of my definition of the show-instance I presume.

Any help is appreciated.

CodePudding user response:

You don't need map; the function supplied to foldr can pattern-match directly.

> foldr (\(MkExpense v _) t -> t   v) 0 [mkExpense "Alex" 40, mkExpense "Gert-Jan" 200]
240.0

CodePudding user response:

map (\(MkExpense amount name) -> amount) [mkExpense "Alex" 40, mkExpense "Gert-Jan" 200] does the trick, having "two constructors" where one flips the arguments caused the confusion as to why my map wasn't working.

  • Related