2013-10-09 109 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