避免类型类中的相互递归默认方法的错误

时间:2012-10-31 08:49:15

标签: haskell types typeclass

  

可能重复:
  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 个答案:

答案 0 :(得分:5)

不幸的是没有。大多数使用默认值定义类型类的库将指定“最小完整定义”,但它们现在不以可检查的方式指定GHC。关于为此实施一个pragma,有一些模糊的说法,但据我所知,并没有什么严重的。

请注意,仅检查相互递归是不够的;相互递归的默认方法可能完全有效,例如Alternative中的somemany