[英]Union of two trees in Haskell
我正在努力在 haskell 中為這個問題的域建模。
我知道如何用過程語言解決這個問題(使用循環,這很容易),但似乎無法弄清楚我將如何在 Haskell 中做到這一點。
我想合並(聯合) RoseDirTree
。
data RoseDirTree
= File Text Int
| Folder Text [RoseDirTree]
deriving (Show, Eq, Ord)
-- | Merges two dir trees
-- If file names are same, prefers the right hands side.
mergeDirTree :: RoseDirTree -> RoseDirTree -> RoseDirTree
mergeDirTree = undefined
這是一個示例案例:
archivesFromS3 :: RoseDirTree
archivesFromS3 = Folder "/"
[ Folder "2011"
[ File "jan.dump" 0
, File "feb.dump" 0
]
, Folder "2012"
[ File "jan.dump" 0
]
]
archivesFromLocal :: RoseDirTree
archivesFromLocal = Folder "/"
[ Folder "2011"
[ File "jan.dump" 1
, File "march.dump" 1
]
, Folder "2019"
[ File "jan.dump" 1
]
]
-- | archivesFromS3 `mergeDirTree` archivesFromLocal
expectedMerged :: RoseDirTree
expectedMerged = Folder "/"
[ Folder "2011"
[ File "jan.dump" 1
, File "feb.dump" 0
, File "march.dump" 1
]
, Folder "2012"
[ File "jan.dump" 0
]
, Folder "2019"
[ File "jan.dump" 1]
]
從更多樹問題的角度來看,我最初的想法是結構必須采用以下形式:
mergeTree :: RoseDirTree -> RoseDirTree -> RoseDirTree
mergeTree (File lhsName idl) (File rhsName idr) =
if lhsName == rhsName
then File rhsName idr
else error "can't merge two different file"
mergeTree (Folder lhsName childl) (Folder rhsName childr) =
if lhsName == rhsName
then Folder rhsName (childl <> childr)
else error "can't merge two different folder"
mergeTree _ _ = error "cannot merge file and folder"
但顯然,這種方法:
我真的不知道下一步該去哪里。 任何指針表示贊賞。
有問題的部分是childl <> childr
。 相反,定義一個新函數:
mergeChildren :: [RoseDirTree] -> [RoseDirTree] -> [RoseDirTree]
mergeChildren = undefined
這個函數應該在某個時候調用mergeTree
函數。
要考慮的事情是您是否可以假設輸入文件和文件夾名稱已排序。 如果它們已排序,您將能夠以更簡單的方式實現它。 如果您被允許使用該功能,您也可以考慮使用Data.List.sortOn
自己對它們進行排序。
如果輸入是排序的,那么這個函數在結構上可以類似於合並排序的合並,例如 Redu 的這個:
merge :: Ord a => [a] -> [a] -> [a] merge [] ys = ys merge xs [] = xs merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys) | otherwise = y:merge (x:xs) ys
不同之處在於您需要不同的比較功能,如果文件夾或文件相等,則需要執行不同的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.