下面的程序导致<<loop>>
GHC。
...明显地。事后看来。
发生这种情况是因为walk
正在计算一个固定点,但有多个可能的固定点。当列表推导到达图形遍历的末尾时,它“询问” ; 的下一个元素answer
。但这正是它已经在尝试计算的。我想我认为程序会到达列表的末尾,然后停止。
我不得不承认,我对这段漂亮的代码有点感伤,希望我能让它工作。
我应该怎么做?
我如何预测“打结”(指表达式中的值,说明如何计算值)是一个坏主意?
import Data.Set(Set)
import qualified Data.Set
-- Like `Data.List.nub`, remove duplicate elements from a list,
-- but treat some values as already having been seen.
nub :: Set Integer -> [Integer] -> [Integer]
nub _ [] = []
nub seen (x:xs) =
if Data.Set.member x seen
then nub seen xs
else x : nub (Data.Set.insert x seen) xs
-- A directed graph where the vertices are integers.
successors :: Integer -> [Integer]
successors x = [(x + 2) `mod` 7, (x + 3) `mod` 7]
-- Breadth first search of a directed graph. Returns a list of every integer
-- reachable from a root set in the `successors` graph.
walk :: [Integer] -> [Integer]
walk roots =
let rootSet = Data.Set.fromList roots
answer = roots ++ nub rootSet [y | x <- answer, y <- successors x]
in answer
main = putStrLn $ show $ walk [0]