3

リスト表現からツリーを復元するために必要な 1 つの型クラスを分解しようとしたときに、興味深い状況に陥りました。アイデアは、要素のプロパティを元の階層で互いに相対的に表現することでした。

データ型の次の特性を考慮する

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) では、重複しない 2 つの機能を持つことは実現不可能であり、余分な作業 ( と のディレクトリを 2 回分割する) が発生する可能性さえありhierarchyCompareますhierarchyJoint。を取得した場合にそれを呼び出す意味がないため、 hierarchyComparebyの機能をカバーすることにしたのはそのためです。hierarchyJointJust _

hierarchyCompare問題は、 object が on で定義されている場合のデフォルトの実装をどのようにするかですHierarchy。たぶん、型クラス間のそのような種類の関係をより説明的な方法で公開できるようにする拡張機能があります(デフォルトの実装を許可します)?

4

3 に答える 3

5

DefaultSignaturesGHC拡張機能を探していると思いますか? それはあなたがすることができます:

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)

次に、空のインスタンス宣言を提供するだけです。

instance HierarchyOrd FilePath 
于 2012-12-16T02:01:57.907 に答える
3

@ dave4420と@ jberrymanの回答に追加するだけです。問題DefaultSignaturesは、デフォルトの実装を、より論理的に適合するサブクラスではなく、スーパークラスで記述する必要があることです。したがって、型クラスを異なるモジュールなどに分割することはできません。 Default superclass instancesと呼ばれるあらゆる種類の同様の問題を解決する提案があります。残念ながらまだ実装されていません。

于 2012-12-16T10:52:33.423 に答える
0

そのような拡張機能は (まだ) ありません。

今のところ、あなたができる最善のことは

defaultHierarchyCompare :: Hierarchy a => a -> a -> Maybe Ordering
defaultHierarchyCompare x y = either Just (const Nothing) (hierarchyJoint x y)

instance Hierarchy FilePath where ...

instance HierarchyOrd FilePath where
    hierarchyCompare = defaultHierarchyCompare
于 2012-12-15T22:19:03.810 に答える