我正在尋找一種智能方法來獲取遍歷給定資料結構的所有路徑。我發現我需要一個這樣的函式:
allPaths :: (a -> [a]) -> a -> [[a]]
它需要一個種子a和一個函式a -> [a](從每個“a”,你可以得到多個 a)。結果是從種子開始的路徑串列。
我的定義是:
allPaths :: (a -> [a]) -> a -> [[a]]
allPaths f a = map (a:) (concatMap (allPaths f) (f a))
但它并不完全有效:
ghci> let f a = if a == 1 then [2, 3] else if a == 2 then [4] else []
ghci> allPaths f 1
[]
結果應該是:[[1,2,4], [1,3]],表示從 1 開始的所有可能路徑。
編輯:我在 Hoogle 中搜索這個簽名,它產生兩個函式:https ://hoogle.haskell.org/?hoogle =% 28a -> [a]) -> a -> [% 5Ba]]&scope=set:stackage 但是,兩者都給了我與我相同的結果。
uj5u.com熱心網友回復:
作為另一個答案的替代方案,如果您想要所有路徑,而不僅僅是到達死胡同的所有路徑,那么您需要[]在每一步都添加解決方案,而不僅僅是最后一步。
allPaths :: (a -> [a]) -> a -> [[a]]
allPaths f a = map (a:) ([] : concatMap (allPaths f) (f a))
根據你的提議f,這給
*Main> allPaths f 1
[[1],[1,2],[1,2,4],[1,3]]
它包括通往死胡同的兩條路徑,就像您的示例一樣,但它也包括[1]和[1,2],它們是有效路徑(它們只是不是有效的最大路徑)。特別是,如果您的圖中有回圈,那么這種方法將生成一個有效的無限路徑串列,而其他建議的答案一旦遇到回圈就無法產生任何結果。
uj5u.com熱心網友回復:
問題是,一旦您到達 a [],您就永遠不會在此之前添加任何內容,因為沒有可以走向的端點。
相反,[]應該表明這是一個端點。
allPaths f a = case f a of
[] -> [[a]]
fa -> map (a:) $ concatMap (allPaths f) fa
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/345088.html
標籤:哈斯克尔
下一篇:資料型別上的Haskell多型性
