I'm struggling to model this problem's domain in haskell.
I know how to solve this in procedural language (with loops, this is rather easy), but can't seem to figure out how I would do this in Haskell.
I want to take merge (union) of 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
Here is an example case:
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]
]
Looking at this from more of tree problem perspective, my initial thought are the structure has to be in form of:
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"
But in-evidently, this approach:
- Does not handle the case when Folder has nested folder with same name.
I'm really not sure where to go next. Any pointers appreciated.