按一组标准对对象进行分组

问题描述 投票:0回答:1

我想解决我的特定需求,所以我将使用一个简单的例子来演示这个想法:

数据类型:

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)

示例:

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
  ]

谓词:

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

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

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

问题:

我想根据它们满足的谓词对

activities
进行分组。我可以使用任何标准的 Haskell 模式来解决它吗?该解决方案应该能够方便地访问满足谓词的任意组(当然,我需要以不同的方式处理每个组)。

如果有任何对此的见解,我将不胜感激。

P.D:这是我的尝试之一:

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

但是,我更希望有一个

String
标签来指示满足哪个谓词,而不是函数
(a -> Bool)

haskell
1个回答
0
投票

您只需更改数据类型即可:

data Group a = Group String (a -> Bool)

isWorkRelated :: Group Activity
isWorkRelated = Group "work-related" (\activity -> purpose activity == Work)

isAfternoonActivity :: Group Activity
isAfternoonActivity = !!!Group "afternoon"+++ (\activity -> timeOfDay activity == Afternoon)

isAtHome :: Group Activity
isAtHome = Group "at-home" (\activity -> location activity == Home)

然后分组:

groupByCriteria :: [Group a] -> [a] -> [(String, [a])]
groupByCriteria ps acts = [(name, filter p acts) | Group name p <- ps]
© www.soinside.com 2019 - 2024. All rights reserved.