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)
.