【发布时间】:2017-09-27 10:13:43
【问题描述】:
编辑: 请参阅 this followup question,这简化了我在此处尝试确定的问题,并要求就 GHC 修改提案提供意见.
所以我试图编写一个通用的广度优先搜索功能并想出了以下内容:
bfs :: (a -> Bool) -> (a -> [a]) -> [a] -> Maybe a
bfs predf expandf xs = find predf bfsList
where bfsList = xs ++ concatMap expandf bfsList
我认为这很优雅,但是在不存在的情况下它会永远阻塞。
在所有术语都扩展为[] 之后,concatMap 将永远不会返回另一个项目,所以concatMap 正在阻止等待来自自身的另一个项目? Haskell 能否变得足够聪明,以实现列表生成被阻止读取自引用并终止列表?
我能想出的最佳替代方案并不那么优雅,因为我必须自己处理终止案例:
where bfsList = concat.takeWhile (not.null) $ iterate (concatMap expandf) xs
对于具体的例子,第一次搜索成功终止,第二次搜索阻塞:
bfs (==3) (\x -> if x<1 then [] else [x/2, x/5]) [5, 3*2**8]
bfs (==3) (\x -> if x<1 then [] else [x/2, x/5]) [5, 2**8]
【问题讨论】:
-
我现在认为添加
takeWhile (not.null)是正确和最简单的解决方案,并且希望是完全明智的事情concat . iterate (const [])实际上应该终止(并且等效于列表的id)。