无限循环哈斯克尔

时间:2015-10-27 21:40:15

标签: haskell infinite-loop ghci

data Node = Node Char [Node] deriving(Eq)

nodeA = Node 'A' [nodeB, nodeC, nodeD]
nodeB = Node 'B' []
nodeC = Node 'C' [nodeE, nodeF]
nodeD = Node 'D' []
nodeE = Node 'E' [nodeB]
nodeF = Node 'F' [nodeA]

deepTraverse :: Node -> [Char]
deepTraverse (Node c []) = [c]
deepTraverse (Node c ns) = c:(map (\(Node cl nsl)->cl) (buildNodeList (Node c ns) ns))
             where lssToLs lss = foldr (++) [] lss
                   buildNodeList nw nsw = lssToLs (map (\(Node cl nsl)->(if (Node cl nsl) == nw then [(Node cl nsl)]
                                                                         else ((Node cl nsl):(buildNodeList nw nsl)))) nsw)

main :: IO()
main = putStrLn (show (deepTraverse nodeA))

每当我打电话给deepTraverse nodeA时,它就会挂起来。在ghci,它确实吐了出来:

Main*> "ABCEBF

让我怀疑"然后" if的一部分。我一直在反对这个问题,我会感激任何帮助。

1 个答案:

答案 0 :(得分:3)

在盯着你的代码多年后试图找出它应该做什么以及它为什么会卡住之后,我想我意识到了这个问题。

nodeF指回nodeA。 (我只是意识到了!)看起来你正试图用==运算符来确定你何时回到你已经看过的节点。那不行。

当您说node1 == node2时,==运算符将遍历整个树,以查看这两个值是否相等。如果它们 相等,并且这个结构包含一个无限循环......那么,你的代码永远循环!试试吧。如果你问nodeA == nodeA,我认为你会发现从不返回。这是你的错误。

解决此问题的唯一方法是在每个Node上添加一个真正的唯一标签,并仅比较标签。你无法检查两个变量在Haskell中是否“指向”同一个东西;你只能比较两个结构是否具有相同的值,这意味着完全遍历它们。