当我尝试分解从列表表示恢复树所需的一个类型类时,我遇到了一个有趣的情况。这个想法是表示元素的属性在原始层次结构中相互关联。
考虑数据类型的下一个特征
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
)。这就是为什么决定涵盖hierarchyCompare
by 的功能,hierarchyJoint
因为如果我们得到Just _
.
问题是:hierarchyCompare
当对象定义在Hierarchy
. 也许有一些扩展允许以更具描述性的方式公开类型类之间的这种关系(允许默认实现)?