我是Haskell的新手,在玩类时偶然发现了这个问题。因此,基本上,我不想在类中定义函数,而是想定义变量。在我的例子中,我在类Maxable
中定义了一个变量maxvalue
。这在Int
上运行得很好。现在假设类型a
是Maxable
的实例,我想定义instance Maxable (Maybe a)
,您可以在我的代码的第三块中看到它不起作用。
class Maxable a where
maxvalue :: a
-- This works fine
instance Maxable Int where
maxvalue = 2147483647
-- Error: Could not deduce (Maxable a1) arising from a use of ‘maxvalue’
instance Maxable a => Maxable (Maybe a) where
maxvalue = maxvalue :: a
我应该用什么来替换CCD_ 7;(可能是a(.maxvalue==a.maxvalue"?
您实际上已经接近正确答案了!
首先,要真正解决这个问题,您需要认识到,在Maybe a
的Maxable
实例中,maxvalue
的类型需要是Maybe a
类型。然而,在您的定义中,您将其设置为a
类型。那么,如何将a
类型的值转换为Maybe a
类型的值呢?您使用Just
构造函数。简而言之,你可以写:
instance Maxable a => Maxable (Maybe a) where
maxvalue = Just maxvalue
事实证明,GHC足够聪明,可以使用正确的maxvalue
,甚至不需要使用:: a
注释。
但是,你的错误怎么办?为什么它告诉你一些关于Maxable a1
的事情?GHC指出的问题来自于您在定义中使用了显式类型签名maxvalue :: a
。默认情况下,GHC不确定类型变量的作用域,因此GHC不知道您想要在实例头中使用相同的a
。GHC假设您只是想要一个新的、新鲜的类型变量,在内部,它决定调用a1
。然后,它对你感到困惑,因为虽然它知道a
是Maxable
(因为你在实例上下文中说过(,但它不知道a1
是Maxable
。
在这种情况下,为了获得更好的错误消息,您可以通过添加来启用GHC扩展ScopedTypeVariables
{-# LANGUAGE ScopedTypeVariables #-}
到文件的顶部。如果使用此语言扩展运行当前代码,则会出现不同的错误,GHC会抱怨a
不等于Maybe a
。如上所述,这可以通过使用Just
构造函数来解决。