2012-10-31 54 views
2

可能重複:
Can GHC warn if class instance is a loop?避免在類型類與相互遞歸默認方法的一個錯誤

考慮一個類型的類有兩個方法,其是可實現在彼此的術語:

class Num a => Foo a where 

    foo :: a 

    bar :: a -> a 
    bar x = baz x + 1 

    baz :: a -> a 
    baz x = bar x - 1 

根據類型的不同,可能會更容易實施barbaz,或者出於效率原因,您可能希望爲其實施兩者。

現在我去別的地方,讓這個類

instance Foo Integer where 
    foo = 1 

哎呀的一個實例,我忘了,要麼實施的或barbaz!沒關係,型號系統會爲我選擇,不是嗎?

C:\path\to\file> ghci Foo.hs 
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
[1 of 1] Compiling Main    (Foo.hs, interpreted) 
Ok, modules loaded: Main. 

嗯,顯然不是。現在,如果我嘗試使用我的班級

*Main> bar 1 
<interactive>: out of memory 

呃哦。提示數小時的痛苦調試。

有沒有辦法讓GHC知道,每個實例都需要指定至少一個barbaz

+1

相關:[可以警告如果類實例是一個循環?](http://stackoverflow.com/questions/12270239/can-ghc-warn-if-class-instance-is-a-loop) – AndrewC

+0

@ AndrewC謝謝。我已經投票結束重複,但我認爲我的問題有一個微妙的區別 - 我不希望編譯器總是*抱怨相互遞歸的默認值,但我*要*選擇告訴它抱怨特定班級。 –

+0

我想這是值得的人類規範,是的,因爲要求編譯器發現相互遞歸是循環的而不是有用的問題很多!也許是一個編譯指示,要求它警告至少有一個(有時是兩個)一組函數會在你創建一個實例時被重新定義(難以指定,展開),或者更好的是,可能存在一個可選的最小規範列表一個地方有一個大的雜注 - 更好)。我沒有仔細閱讀[trac ticket](http://hackage.haskell.org/trac/ghc/ticket/6028)。 – AndrewC

回答

5

不幸的不是。大多數定義具有默認類型類的庫將指定一個「最小完整定義」,但是它們現在並沒有以可檢查的方式將它指定給GHC。關於爲此編寫一個附註有些模糊的說法,但據我所知沒什麼嚴重的。

請注意,只檢查相互遞歸是不夠的;相互遞歸的默認方法可能是完全有效的,例如, somemany in Alternative