考慮以下 Python 函式,該函式在給定節點的后繼節點的情況下,訪問它們并收集結果。(實際上,此邏輯將構成遞回visit函式的一部分。)
from typing import Any, Callable, Tuple, List, Set
Node_key = Any
Discovered = Set[Node_key]
Result = Any
def get_successor_results(visit: Callable[[Discovered, Node_key],
Tuple[Discovered, Result]],
successors: List[Node_key],
disc: Discovered) -> List[Result]:
results = []
for succ in successors:
if succ not in disc:
disc, result = visit(disc, succ)
results.append(result)
return results
(對于背景關系,這將是 df-traverse 函式的一部分,給定一個圖和一個函式combiner :: Node_key -> [Result] -> Result,它相當于構建深度優先森林并呼叫fold-tree combiner每棵樹。)
我的問題:你會如何
get_successor_results用 Haskell撰寫?
一些想法:
get-successor-results visit successors disc =
reverse . first . conditional-fold
(\(d, _) node -> not (elem node d))
(cons-next-result visit)
(empty-set, [])
successors
where
cons-next-result visit _@(disc, results) node =
let (disc-new, result) = visit disc node
in (disc-new, result:results)
conditional-fold p folder e xs = case xs of
{[] -> e;
x:xs' -> if p e x then conditional-fold p folder (folder e x) xs'
else conditional-fold p folder e xs'}
uj5u.com熱心網友回復:
直接翻譯它看起來很簡單:
get_successor_results ::
(node_key -> discovered -> Bool) ->
(node_key -> State discovered result) ->
[node_key] ->
State discovered [result]
get_successor_results not_in visit successors = do
results <- for successors $ \succ -> do
should_visit <- gets (succ `not_in`)
if should_visit
then Just <$> visit succ
else return Nothing
return (catMaybes results)
希望與您的 Python 代碼的相似之處是清楚的。這里唯一真正的轉折是Nothing用作您不想訪問的繼任者的占位符,然后將其剝離作為第二步。當然,我建議你使用駝峰式命名;這是 Haskell 中的一個強大約定,因此它將更好地與現有庫呼叫融合,但我希望相似之處盡可能明顯,因此我盡可能使用與 Python 代碼相同的名稱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/404594.html
標籤:
