类型类是Haskell中另一个和默认实现的超集

ony*_*ony 3 haskell programming-languages typeclass

当我尝试分解从列表表示中恢复树所需的一个类型类时,我遇到了一个有趣的情况.我们的想法是在原始层次结构中将元素的属性表示为彼此相对.

考虑数据类型的下一个特征

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)
Run Code Online (Sandbox Code Playgroud)

正如您所看到HierarchyOrderingHierarchy,我们只需要实现排序而不需要构建新节点.在这种特定的情况下(FilePath具有两个非重叠的功能)是不可行的,甚至可能导致额外的工作(分裂目录两次hierarchyComparehierarchyJoint).这就是为什么我们决定支付功能hierarchyCompare通过hierarchyJoint,因为它是没有意义调用它,如果我们得到了Just _.

问题是:如何hierarchyCompare定义对象的默认实现Hierarchy.也许有一些扩展允许以更具描述性的方式暴露类型类之间的这种关系(允许默认实现)?

jbe*_*man 5

我想你在寻找GHC DefaultSignatures扩展?那就是你做的:

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
    default hierarchyCompare :: Hierarchy a=> a -> a -> Maybe Ordering
    hierarchyCompare x y = either Just (const Nothing) (hierarchyJoint x y)
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地提供一个空的实例声明:

instance HierarchyOrd FilePath 
Run Code Online (Sandbox Code Playgroud)