安全实例覆盖

时间:2013-10-09 16:59:07

标签: haskell override newtype

假设类型A是类C的实例。

如果我理解正确,要覆盖实例实现,通常会引入包装器newtype A' = A' A,然后将A的所有出现包装在A'中。

但是,如何确保你不小心忘记包装一些A,并且所有A都使用新的实现?

我们能为此做些什么吗?

2 个答案:

答案 0 :(得分:1)

如果您的函数依赖于C提供的A'的自身实现,则可以在该函数的类型签名中表达它。所以没有

fGeneric :: C a => a -> b

你只需要使用

fSpecific :: A' -> b

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

答案 1 :(得分:1)

通过递归调用A,您可以查明某些单态类型是否包含A'不在包装器Language.Haskell.TH.reify内。这是一个混乱的例子:http://lpaste.net/94105。如果出现以下情况,则会失败:

  • reify未提供所需信息。有时它不提供与给定名称对应的定义。
  • 包含A实例的类型,但不必提及类似HiddenA下面的类型

    data HiddenA = forall a. C a => HiddenA a
    instance C HiddenA where f (HiddenA x) = f x
    
  • 无法保证您实际将检查应用于您使用的功能

但至少它是一个编译时检查。