我试图评论所有内容,以使我的代码对每个人都非常清楚。请阅读评论以便更好地理解。
到目前为止,我所拥有的是由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
答案 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})
>