2010-03-13 61 views
9

在Haskell中派生實例時,是否可以爲任意類型派生函數,還是僅限於特定函數?在Haskell中派生任意函數

+0

嘿嘿,+1,如果你發現這個是因爲你希望你能爲ADT派生'Test.QuickCheck.Arbitrary'。 :) – 2013-11-25 16:10:12

回答

9

您可以在haskell 98中派生出以下類的實例:Eq,Ord,Enum,Ix,Bounded,Read和Show。

使用ghc擴展,您還可以派生下列類的實例:Typeable,Data,Functor,Foldable和Traversable。還有一個ghc擴展,它允許newtype從其實現類型派生實例。

你不能派生任意類的實例,原因很簡單,因爲haskell不知道如何在沒有關於該類的特殊知識的情況下生成必要的函數。

+0

但GHC可以處理一些簡單的情況。如果你說'newtype Bar = Bar Foo'並且Foo有一個Quux實例,那麼GeneralizedNewtypeDeriving可以爲你導出Bar的Quux實例。當然,這只是微不足道的展開,但總比沒有好。 – jrockway 2010-03-13 04:59:54

6

根據編譯器知道如何爲您推導,您被限制在特定的類中。使用預處理器或模板Haskell,如果您知道爲特定類型生成函數實現的一般方法,您可以自己編寫新的派生機制。

6

另外兩個答案是正確的。但是如果你需要更多的東西,那麼就有一些可以處理更多的軟件包。我喜歡Data.Derive很多,因爲您可以直接生成源代碼(爲了兼容性)或將其掛接到模板哈斯克爾在編譯時執行它。各種各樣的類已經被支持,並且很容易爲你自己添加支持。摘要:爲該死的罰款庫:-)

+0

我現在把它拿回來。我當時還沒有試圖增加對自己的支持,但我認爲這很容易。它不是;它涉及重新編譯我可以告訴的圖書館。但內置的支持仍然不錯並且完整。 – luqui 2011-04-21 19:50:18

4

廣告間距要添加到唐的回答是:獲得定製功能爲數據類型被稱爲generic programming並有一個lot of literature這個問題。預處理器和模板Haskell不是唯一的解決方案;請參閱其中一份概述文件,列出其他選項的文獻。