Haskell:在类型类中定义一个变量



我是Haskell的新手,在玩类时偶然发现了这个问题。因此,基本上,我不想在类中定义函数,而是想定义变量。在我的例子中,我在类Maxable中定义了一个变量maxvalue。这在Int上运行得很好。现在假设类型aMaxable的实例,我想定义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 aMaxable实例中,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。然后,它对你感到困惑,因为虽然它知道aMaxable(因为你在实例上下文中说过(,但它不知道a1Maxable

在这种情况下,为了获得更好的错误消息,您可以通过添加来启用GHC扩展ScopedTypeVariables

{-# LANGUAGE ScopedTypeVariables #-}

到文件的顶部。如果使用此语言扩展运行当前代码,则会出现不同的错误,GHC会抱怨a不等于Maybe a。如上所述,这可以通过使用Just构造函数来解决。

最新更新