考虑一个类型类,它有两个可以相互实现的方法:
class Num a => Foo a where
foo :: a
bar :: a -> a
bar x = baz x + 1
baz :: a -> a
baz x = bar x - 1
根据类型的不同,实施bar
或baz
可能更容易,或者出于效率原因,您可能希望实施这两种方法。
现在我去别的地方做一个这个类的实例
instance Foo Integer where
foo = 1
糟糕,我忘了实施bar
或baz
的 !没关系,类型系统会为我挑选,不是吗?
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知道每个实例都需要指定至少一个 bar
或baz
?
答案 0 :(得分:5)
不幸的是没有。大多数使用默认值定义类型类的库将指定“最小完整定义”,但它们现在不以可检查的方式指定GHC。关于为此实施一个pragma,有一些模糊的说法,但据我所知,并没有什么严重的。
请注意,仅检查相互递归是不够的;相互递归的默认方法可能完全有效,例如Alternative
中的some
和many
。