python - 将递归大小写转换为 Haskell 时遇到问题
问题描述
我有以下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
是一个字典,like{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
循环。
解决方案
这应该有效:
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
所以你根本不用处理Maybe
。正如 AChampion 指出的那样,您不需要if
测试,因为如果列表为空,则会自动发生正确的事情。
not $ any f adjListAtstarting
f
对 的每个元素调用函数adjListAtstarting
,True
如果所有调用都返回则f
返回False
,但False
如果有任何调用返回则f
返回True
。这与您的 Python for 循环相匹配,False
如果内部测试是 ever 则立即返回,如果循环退出则True
返回True
,因为内部测试总是错误的。
filter (vertex /=)
接受一个列表,并返回一个包含除 . 之外的所有元素的列表vertex
。(注意:您remove
在 Python 中使用,它只从列表中删除第一次出现的元素。这将从列表中删除所有匹配的元素。如果列表永远不会包含两个相同的元素,那么这很好。如果他们这样做了,那么您将需要使用该delete
函数(从 导入Data.List
)。)
Map.adjust (filter (vertex /=)) start adjList
调用filter (vertex /=)
的start
元素adjList
,并返回一个映射,其中该调用的结果是start
输入中元素的替换,并且所有其他元素都是相同的。(您只需要adjust
和不需要adjustWithKey
,因为您对值所做的更改不依赖于密钥。)
推荐阅读
- intellij-idea - 环绕选择成阵列
- python - 如何在散点图中显示重叠点?
- python - 如何在中间视图django中打开带有html或对话框的窗口
- javascript - 类类型化的 Rest 参数被视为来自打字稿的任何参数
- sql-server - IntelliJ 无法查询 SQL Server 数据库并返回空错误消息
- c++ - 类之间的信息丢失
- regex - Flutter / Dart - 为 RegExp 的多个匹配项解析 Textfield 控制器文本,并在每次匹配时调用一个函数
- assembly - 在 8086 中读取文件直到文件结束
- scala - 在 IntelliJ 中找不到 PlaySpec
- c++ - MS Detours 绕道函数未被调用