Grouping objects by a set of criteria

  Kiến thức lập trình

I want to solve a particular need I have, so I will demonstrate the idea using a simple example:

Datatypes:

data Activity = Activity
  { activityName :: String
  , purpose :: Purpose
  , timeOfDay :: TimeOfDay
  , location :: Location
  }
  deriving (Show, Eq)

data Purpose = Work | Personal | Leisure
  deriving (Show, Eq)

data TimeOfDay = Morning | Afternoon | Evening
  deriving (Show, Eq)

data Location = Home | Office | Elsewhere
  deriving (Show, Eq)

Example:

activities =
  [ Activity "Check emails" Work Morning Office
  , Activity "Attend project meeting" Work Afternoon Office
  , Activity "Go for a run" Leisure Afternoon Elsewhere
  , Activity "Prepare dinner" Personal Evening Home
  , Activity "Watch a movie" Leisure Evening Home
  , Activity "Read a book" Leisure Evening Home
  ]

Predicates:

isWorkRelated :: Activity -> Bool
isWorkRelated activity = purpose activity == Work

isAfternoonActivity :: Activity -> Bool
isAfternoonActivity activity = timeOfDay activity == Afternoon

isAtHome :: Activity -> Bool
isAtHome activity = location activity == Home

Problem:

I would like to group activities according to the predicate(s) they satisfy. Are there any standard Haskell pattern I can use to solve it ? The solution should enable convenient access to an arbitrary group that satisfies a predicate (I would then need to process each of them in a different way, of course).

I would appreciate any insights into this.

P.D: This is one of my attempts:

groupByCriteria :: [a -> Bool] -> [a] -> [(a -> Bool, [a])]
groupByCriteria ps acts = [(p, filter p acts) | p <- ps]

However, I would prefer to have a String label to indicate which predicate is satisfied instead of a function (a -> Bool).

LEAVE A COMMENT