为什么GHC只警告部分实现的类,而不是错误?

Tid*_*ddo 11 haskell typeclass ghc

我认为标题已经自我解释了,但是这里有一个例子来说明我的观点:

class Foo a where
    someFunction :: a -> a -> Bool

instance Foo Bool
Run Code Online (Sandbox Code Playgroud)

当我编译它时,编译器会发出警告:

Warning:
    No explicit method or default declaration for `someFunction'
    in the instance declaration for `Foo Bool'
Run Code Online (Sandbox Code Playgroud)

调用该函数现在将导致运行时错误.为什么这是一个警告,而不是编译时错误?有没有办法使这成为编译时错误?

Zet*_*eta 9

所述GHC文档提供了一个例子,其中一个警告是足够:

-fwarn-missing-methods:

默认情况下,此选项处于启用状态,并在实例声明缺少一个或多个方法时发出警告,并且相应的类声明没有默认声明.

如果方法名称以下划线开头,则会禁止警告.这是一个有用的例子:

class C a where
  _simpleFn :: a -> String
  complexFn :: a -> a -> String
  complexFn x y = ... _simpleFn ...
Run Code Online (Sandbox Code Playgroud)

这个想法是:(a)班级用户只会打电话complexFn; 从未_simpleFn; (b)实例声明可以定义complexFn或_simpleFn.

该MINIMAL编译指示可用于更改特定类的实例所需的方法组合.请参见第7.20.5节"MINIMAL pragma".

这就是缺少方法不会导致错误的原因,而是一个警告.如果你想使警告致命,请使用-Werror.由于没有-ferr-missing-methods,-Werror是制作-fwarn-missing-methods编译器错误的唯一方法.

  • 在上面的示例中正确指定 MINIMAL pragma 来修复警告/错误难道还不够吗?即在上面的示例中添加 `{-# MINIMAL _simpleFn | complexFn #-}` 也会让编译器满意,因此仍然不会给出缺少方法的原因以发出警告而不是错误。 (3认同)
  • @Tiddo:真正的原因可能是一个历史性的原因。话虽如此,人们可以修补 [`warnMissingMethodOrAT`](https://github.com/ghc/ghc/blob/33cfa5ff9db4e7886b3e7c2eed5ac1c75436bc4c/compiler/typecheck/TcInstDcls.hs#L1614-L1622) 来创建你想要的行为。您可以提交问题/功能请求。 (3认同)