Haskell:操纵已定义类的数据类型

时间:2018-02-27 21:39:20

标签: haskell

我试图评论所有内容,以使我的代码对每个人都非常清楚。请阅读评论以便更好地理解。

到目前为止,我所拥有的是由Team组成的球员,这些球员最终将获得一个位置:后卫,中场或前锋。例如,在:

let ykTeam = Team(Map.fromList [(1, [ 2, 3]),  (2, [1]), (3, [1, 4]), (4, [3])])

项目(1, [ 2, 3])意味着玩家1也可以玩2或3(现在不那么重要)。

问题:从下面显示的代码中,我想编写initPlan函数,但我正在努力操纵Plan属性{{1} }。

预期结果:当我尝试:

planMap :: Map.Map p Position

我需要得到:

> initPlan $ team 4

备注:我习惯Plan(def={}, mid={}, stk={1,2,3,4}) 但不习惯Map.Map v k ???

欢迎任何迹象,想法或提示。

我的代码是:

Map.Map v Position

import Data.List (intercalate) import qualified Data.Map as Map -- | The possible position of players on the field: -- -- * `def`: the player is a defender in the team; -- * `mid`: the player is a midlefield in the team; -- * `stk`: the player is a stiker in the team; data Position = Def | Mid | Stk deriving (Eq, Show) data Team t = Team (Map.Map t [t]) -- | A Plan for enumerating team position. data Plan p = Plan { planMap :: Map.Map p Position, planTeam :: Team p } instance (Show p, Ord p) => Show (Plan p) where show p@(Plan playerToPosition _) = "Plan(" ++ "defender={" ++ (showByPosition Def) ++ "}, " ++ "midlefield={" ++ (showByPosition Mid) ++ "}, " ++ "stiker={" ++ (showByPosition Stk) ++ "})" where showByPosition a = intercalate "," $ map show $ playersByPosition a p playersByPosition :: Ord p => Position -> Plan p -> [p] playersByPosition position = Map.keys . Map.filter (== position) . planMap 的签名是:

initPlan

1 个答案:

答案 0 :(得分:4)

我想你可能想要:

initPlan :: Ord p => Team p -> Plan p
initPlan team@(Team tmap) = Plan pmap team
  where pmap = Map.fromList $ map (\plyr -> (plyr, Stk)) plyrs
        plyrs = Map.keys tmap

给定Team,这将从底层地图中的键获取完整的玩家列表(plyrs)。然后我们可以作为列表构建对:(1,Stk)(2,Stk)等等,将每个玩家分配到前锋位置,然后从该列表构建地图。

您没有提供team功能的定义,因此我不知道team 4应该是什么样的,但使用ykTeam定义以上似乎有效:

> initPlan ykTeam
Plan(defender={}, midlefield={}, stiker={1,2,3,4})
>