我有以下python代码:
def win(start, adjList):
if len(adjList[start]) == 0: return True
else:
for vertex in adjList[startingPoint]:
adjListCopy = copy.deepcopy(adjList)
adjListCopy[start].remove(vertex)
if (win(vertex, adjListCopy)): return False
return True
这里adjList
是字典,类似于{0: [1,2], 2: [3], 3: []}
,而start是要查看的索引,在这种情况下,假设start是0
。如果我们从0
开始,那么如果我们赢了,它将返回。
在haskell中,我将字典表示为Map
到目前为止,这是我的代码:
win adjList start =
if (adjListAtstarting) == Just [] || (adjListAtstarting) == Nothing
then True
else
False
-- loop through each item in the map, and recurse
where adjListAtstarting = Map.lookup start adjList
在haskell中的递归情况下,我需要帮助。我知道我可以使用adjListCopy[start].remove(vertex)
函数执行Map.adjustWithKey
。我遇到麻烦的主要原因是因为for
循环。
答案 0 :(得分:1)
这应该有效:
import qualified Data.Map as Map
win adjList start = not $ any f adjListAtstarting
where adjListAtstarting = Map.findWithDefault [] start adjList
f vertex = win (Map.adjust (filter (vertex /=)) start adjList) vertex
由于您无论如何都要处理Just []
和Nothing
,因此我使用findWithDefault
而不是lookup
,因此您不必处理{{1 }}。正如AChampion指出的那样,您不需要进行Maybe
测试,因为如果列表为空,则自动发生正确的事情。
if
在not $ any f adjListAtstarting
的每个元素上调用函数f
,如果对adjListAtstarting
的所有调用都返回了{{1},则返回True
},但如果对f
的任何调用返回了False
,则返回False
。这与您的Python for循环匹配,如果内部测试曾经是f
,则它立即返回True
,如果由于内部测试始终为false而退出循环,则返回False
。
True
获取一个列表,并返回一个列表,其中包含True
以外的所有元素。 (注意:您在Python中使用了filter (vertex /=)
,这只会从列表中删除第一次出现的元素。这将从列表中删除所有匹配的元素。如果列表永远不会包含两个相同的元素,则如果这样做,那么您将需要使用the delete
function (imported from Data.List
)。)
vertex
在remove
的{{1}}元素上调用Map.adjust (filter (vertex /=)) start adjList
,并返回一个映射,其中该调用的结果是filter (vertex /=)
元素的替换在输入中,其他所有元素都相同。 (您只需要start
而不是adjList
,因为您对值所做的更改不依赖于键。)