2013-10-09 77 views
2

假设有一个类型A,它是类C的实例。安全实例覆盖

如果我理解正确,为了覆盖实例实现,通常会引入一个包装newtype A' = A' A,然后将所有发生的A包装在A'中。

但是,如何确保您不会意外忘记包装某些A s,并且所有A都使用新的实施?

我们可以做点什么吗?

回答

1

如果您的功能依赖于您自己的提供的C的实现,您可以在该函数的类型签名中表示它。因此不是

fGeneric :: C a => a -> b 

你只想用

fSpecific :: A' -> b 

,所以你知道你会得到哪些行为。

+0

是的,这是我的实现,但它然后被库函数使用,我不能改变它。 – lambdas

1

你可以通过递归地调用Language.Haskell.TH.reify找出是否包含A的某些单形类型不在包装A'中。以下是这样一个混乱的例子:http://lpaste.net/94105。这将失败,如果:

  • reify不提供所需的信息。有时它不提供与给定名称相对应的定义。
  • 包含为实例,但没有提到像HiddenA类型下面

    data HiddenA = forall a. C a => HiddenA a 
    instance C HiddenA where f (HiddenA x) = f x 
    
  • 没有保证,你实际上检查适用于您使用

功能类型

但至少这是编译时检查。

+0

哇,我不知道哈斯克尔这种事情是可能的。但正如你所说,现在应该记住应用支票。谢谢。 – lambdas