Haskell 递归地在字典上循环并删除键

Haskell 递归地在字典上循环并删除键,haskell,dictionary,recursion,Haskell,Dictionary,Recursion,我正在使用顶点和一个Data.Map为跳棋游戏尝试捕捉动作。我正在使用函数changeKey更新地图中的当前键,并使用函数cMove进行捕获移动。现在,cMove获取一个顶点、一个顶点列表(包含对手棋子)和一个包含顶点和布尔值的地图,以指示棋子属于哪个玩家cMove检查第一个顶点元组是否在地图中(当计算找到有效移动的位置时,知道板上的位置是否为空)。如果是,将调用changeKey changeKey :: (Integer, Integer) -> (Integer, Integer)

我正在使用顶点和一个
Data.Map
为跳棋游戏尝试捕捉动作。我正在使用函数
changeKey
更新地图中的当前键,并使用函数
cMove
进行捕获移动。现在,
cMove
获取一个顶点、一个顶点列表(包含对手棋子)和一个包含顶点和布尔值的地图,以指示棋子属于哪个玩家
cMove
检查第一个顶点元组是否在地图中(当计算找到有效移动的位置时,知道板上的位置是否为空)。如果是,将调用
changeKey

changeKey :: (Integer, Integer) -> (Integer, Integer) -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool
changeKey k0 k1 myMap = case M.updateLookupWithKey (\_ _ -> Nothing) k0 myMap of
         (Nothing, _    ) -> myMap
         (Just e, myMap) -> M.insert k1 e myMap

cMove :: (Integer, Integer) -> [(Integer, Integer)] -> Map (Integer, Integer) Bool -> Map (Integer, Integer) Bool
cMove k [k1] myMap = if M.notMember (2*fst k1 - fst k, 2*snd k1 - snd k) myMap
                          then
                          changeKey k (2*fst k1 - fst k, 2*snd k1 - snd k) myMap
                          else myMap
我这里的问题在于,如果列表包含多个元组,我不知道如何循环遍历顶点列表(因为玩家每回合可以执行无限量的捕获)。此外,我如何确保代表对手棋子的每个键都将从地图中删除。

首先,建议您在类似情况下使用
Data.map.Strict
而不是
Data.map

此外,函数名通常应以小写字母开头


有了这些,这里进行迭代的一个简单方法是将其转换为最终结果
Map
。您编写一个函数来处理一次迭代(请参见下面的
cMove'
),然后使用类似
foldr
foldl'
的方法让它为您完成所有迭代

我不确定下面是否给出了您想要的行为,但这里有一个使用
foldr
的初稿:

import Data.Map.Strict(Map(..)
导入符合条件的Data.Map.Strict作为M
changeKey::(整数,整数)->(整数,整数)->映射(整数,整数)布尔->映射(整数,整数)布尔
changeKey k0 k1 myMap=case M.updateLookupWithKey(\\\\\->Nothing)k0 myMap of
(无任何内容)->myMap
(仅e,myMap)->M.插入k1 e myMap
cMove::(整数,整数)->[(整数,整数)]->映射(整数,整数)布尔->映射(整数,整数)布尔
cMove k ks myMap=foldr(cMove'k)myMap ks
哪里
cMove'::(整数,整数)->(整数,整数)->映射(整数,整数)布尔->映射(整数,整数)布尔
cMove'k k1 myMap=如果M.notMember(2*fst k1-fst k,2*snd k1-snd k)myMap
然后更改密钥k(2*fstk1-fstk,2*sndk1-sndk)myMap
我的地图

您不应该使用类似这样的函数调用:
fst(k1)
。您应该只使用
fstk1
,比如
2*fstk1-fstk
。感谢您的反馈。从其名称的拼写来看,
ChangeKey
不能是函数。编辑以修复
ChangeKey
大小写。它正在实现。一个问题是,新的k不用于列表的其余部分,而旧的k用于列表的其余部分。为了澄清这一点,每当调用changeKey时,cMove都应该使用新的顶点k而不是原来的顶点k。因此,如果列表是
[a,b,c,d,e]
,它应该第一次使用
k
a
,第二次使用
a
b
,第三次使用
b
c
,等等?