根据子类优化超类方法

博尔帕特

当类型也位于另一个类中时,是否可以在类实例中提供方法的改进实现(也称为OOP中的重写)?或者至少,如果该其他类是子类。

我有一个C带有methodm的类SC带有method的子类s和一个类型,T a所以有实例化

class C a where m :: [a] -> Bool
class C a => S a where s :: a -> a -> Bool
instance C a => C (T a) where m = ...
instance S a => S (T a) where s = ...

照常。现在碰巧是,当T a在子类中时(我不知道它依赖于什么a),使用方法m可以实现更高效的方法(二次与指数时间)s

m在实现中尝试了“覆盖”

instance S a => S (T a) where
    s = ...
    m = (all . uncurry) (=^=) . pairs -- override C.m

但是编译器的错误基本上是因为,m不是的公共方法S嗯,不是,而是从面向对象的角度继承的。

出于特定目的,m可以将的专用版本用于所有实例;它不是默认值可以在任何地方覆盖。


编辑:由于要求,具体代码带有一些解释。

我有一个Model具有(其中包括)一种方法的方法con该方法检查列表的一致性。

class Model a where
    con :: [a] -> Bool

两个模型可以形成箭头模型。

data Arrow a b = [a] :->: b
lhs w = [ a | (u :->: _) <- w, a <- u ]
rhs w = [ b | (_ :->: b) <- w ]

对于特定实例Model (Arrow a b),一般con实现非常昂贵(powerset定义中要注意)。

instance (Model a, Model b) => Model (Arrow a b) where
    con w = all (\w' -> con (lhs w') `implies` con (rhs w')) (powerset w)

有一个子类CoherentModelModel子类具有一种(=^=)检查两个对象一致性的方法相干模型的条件是,如果所有对都是一致的,则列表是一致的。

class Model a => CoherentModel a where
    (=^=) :: a -> a -> Bool
    a =^= b = con [a, b]

CoherentModel到目前为止,该类的文档多于功能。

因此,假设模型是连贯的,则一致性检查的效率要高得多。

instance (Model a, CoherentModel b) => CoherentModel (Arrow a b) where
    (u :->: a) =^= (v :->: b) = con (u ++ v) `implies` a =^= b

并且在这种情况下,con可以使用

con = (all . uncurry) (=^=) . pairs
  where
    pairs :: [a] -> [(a,a)]
    pairs [] = []
    pairs [_] = []
    pairs [x,y] = [(x,y)]
    pairs (x:xs) = map ((,) x) xs ++ pairs xs

但我找不到指定此方法的方法。它不仅适用于Arrow,而且还与所有带参数的模型有关。我之所以选择,Arrow是因为改进非常明显。

卢基

这是一个好问题。要记住的一件事是,数据类型是否是类型类的实例编译时的信息,即,我们始终能够在使用站点上使用静态可用信息来选择使用哪个实例,而多态性源于能够从上下文中选择一个实例。通常,如果您询问“是否是atypeclass的成员B?”,则只能获得“是”和“编译错误”的答案。(第二个观察值被改变了一点OverlappingInstances,但对您的情况似乎没有帮助)

因此,您眼前的问题的答案是否定的除非您是该类型类的方法,否则您不能对类型在类型类中的成员资格做出决定。我们可以做的就是将此决定添加为方法(使用constraints软件包)

import Data.Constraint

class Model a where
    con :: [a] -> Bool
    isCoherent :: Maybe (Dict (CoherentModel a))
    isCoherent = Nothing

您可以为实例化的任何类型简单定义CoherentModel

instance Model Foo where
    con = ...
    isCoherent = Just Dict

现在,您可以像这样执行您的决定(带有扩展名ScopedTypeVariablesTypeApplications):

instance (Model a, Model b) => Model (Arrow a b) where
    con | Just Dict <- isCoherent @b = -- efficient implementation
        | otherwise                  = -- inefficient implementation

在第一种情况下,我们将CoherentModel b在上下文中具有局部变量。挺酷的

太糟糕了,我们这里有一个表达问题,其中所有con需要的不同实现都需要集中到一个地方。同样太糟糕的是,isCoherent需要在每个连贯Model实例上手动实现,与CoherentModel实例所在的位置分开

这里有很多值得探索的地方,但我必须走了。祝好运!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章