假设有一个类型A
,它是类C
的实例。安全实例覆盖
如果我理解正确,为了覆盖实例实现,通常会引入一个包装newtype A' = A' A
,然后将所有发生的A
包装在A'
中。
但是,如何确保您不会意外忘记包装某些A
s,并且所有A
都使用新的实施?
我们可以做点什么吗?
假设有一个类型A
,它是类C
的实例。安全实例覆盖
如果我理解正确,为了覆盖实例实现,通常会引入一个包装newtype A' = A' A
,然后将所有发生的A
包装在A'
中。
但是,如何确保您不会意外忘记包装某些A
s,并且所有A
都使用新的实施?
我们可以做点什么吗?
如果您的功能依赖于您自己的提供的C
的实现,您可以在该函数的类型签名中表示它。因此不是
fGeneric :: C a => a -> b
你只想用
fSpecific :: A' -> b
,所以你知道你会得到哪些行为。
你可以通过递归地调用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
没有保证,你实际上检查适用于您使用
但至少这是编译时检查。
哇,我不知道哈斯克尔这种事情是可能的。但正如你所说,现在应该记住应用支票。谢谢。 – lambdas
是的,这是我的实现,但它然后被库函数使用,我不能改变它。 – lambdas