當我嘗試分解一個需要從列表表示中恢復樹的類型類時,我遇到了一個有趣的情況。這個想法是表示元素的屬性在原始層次結構中是相對於其他元素的。Typeclass是Haskell中另一個和默認實現的超集
考慮數據類型
class HierarchyOrd a where
-- | Compares two objects for being on the same branch of hierarchy
-- LT/GT lower/higher in hierarchy, EQ on the same node
hierarchyCompare :: a -> a -> Maybe Ordering
class HierarchyOrd a => Hierarchy a where
-- | Get information for common joint of branches for two objects
-- Either one of them already on joint node (parent)
-- or we need another object that represent that joint
hierarchyJoint :: a -> a -> Either Ordering a
-- hierarchyCompare x y = either Just (const Nothing) (hierarchyJoint x y)
-- Sample for FilePath
instance Hierarchy FilePath where
hierarchyJoint x y = case (length x', length y', length z') of
(a, b, c) | a == c && b == c -> Left EQ
(a, _, c) | a == c -> Left GT
(_, b, c) | b == c -> Left LT
_ -> Right (joinPath z')
where
[x', y'] = map splitDirectories [x, y]
skel = takeWhile id (zipWith (==) x' y')
z' = zipWith const x' skel -- common prefix
instance HierarchyOrd FilePath where
hierarchyCompare x y = either Just (const Nothing) (hierarchyJoint x y)
的下一個特質正如你所看到HierarchyOrdering
是Hierarchy
一個子集,我們只需要實現排序,無需建設新的節點。在這種特殊情況下(FilePath
)具有兩個不重疊的功能是不可行的,甚至可能導致額外的工作(爲hierarchyCompare
和hierarchyJoint
分裂目錄兩次)。這就是爲什麼決定通過hierarchyJoint
覆蓋hierarchyCompare
的功能,因爲如果我們得到Just _
就沒有意義了。
問題是:當在Hierarchy
上定義對象時,如何使用默認實現hierarchyCompare
。也許有一些擴展允許以更具描述性的方式暴露類型類之間的這種關係(允許默認實現)?
是的,這就是我一直在尋找的。我的確希望這個擴展有點不同的設計。特別是當我有幾個超集時,會有一個問題。但是這個變體也允許有更復雜的上下文而不僅僅是一個類型'Hierarchy a'。謝謝 – ony