为什么在Haskell中的实例定义中期望构造函数

Key*_*nan 1 haskell class instance

谁能解释这个错误:

实例头中的语法错误(预期的构造函数)

class Nullable v where
  default_val :: v


instance Num a => Nullable a where  -- error reported here
  default_val = 0::a
Run Code Online (Sandbox Code Playgroud)

谢谢

Joh*_*n L 8

首先,hackage让你满意.

其次,不要写表单的实例

instance OtherClass a => Class a where
Run Code Online (Sandbox Code Playgroud)

他们不像你想要的那样工作.(YMMV与GHC以外的编译器,但即便如此,我也看不出它是个好主意).大概你的意图是创建几个实例,例如:

instance Num a => Nullable a where  -- error reported here
  default_val = 0::a

instance Bounded a => Nullable a where
  default_val = minBound
Run Code Online (Sandbox Code Playgroud)

您可以将类型类约束视为函数的额外参数,如下所示:

instance Num a => Nullable a where
  default_val = NumDict a -> 0::a

instance Bounded a => Nullable a where
  default_val = BoundedDict a -> minBound
Run Code Online (Sandbox Code Playgroud)

然后ghc实际上看到这样的类实例如下:

instance Nullable a where
  default_val = NumDict a -> 0::a

instance Nullable a where
  default_val = BoundedDict a -> minBound
Run Code Online (Sandbox Code Playgroud)

现在,编译器应该选择哪个实例?有两个实例都声称对所有类型都有效.所以有一个编译器错误.

即使您有一个基于类型类的实例,这也是一个问题.假设您有这些实例:

instance Num a => Nullable a where
  default_val = 0::a

instance Nullable String where
  default_val = ""

instance Nullable BS.ByteString where
  default_val = BS.empty
Run Code Online (Sandbox Code Playgroud)

第一个仍然被认为对所有类型都有效,所以ghc说它需要OverlappingInstances扩展来全部使用它们.那不完全是邪恶的.但是当你试图使用它时,不久之后ghc将需要另一个扩展,IncoherentInstances.

很多人都害怕使用UndecidableInstances,但这种恐惧是错误的.可能发生的最坏情况UndecidableInstances是编译不会终止(但通常会终止). IncoherentInstances是应该激发恐惧的延伸,因为它会给你的代码带来厄运.如果GHC说您必须启用IncoherentInstances,则意味着您需要更改代码.

TL;博士

不要写表单的实例

instance OtherClass a => Class a where
Run Code Online (Sandbox Code Playgroud)

他们不做你想做的事.