Haskell:在类型类中定义变量

我是 Haskell 的新手,在玩类时偶然发现了这个问题。所以基本上不是在类中定义函数,我想定义变量。就我而言,我maxvalue在 class 中定义了一个变量Maxable。这对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

我应该用什么替换maxvalue = maxvalue :: a,以便“(也许 a).maxvalue == a.maxvalue”

回答

您实际上非常接近正确答案!

首先,要真正解决问题,您需要认识到在您的Maxable实例 for 中Maybe a,类型maxvalue需要是类型Maybe a。但是,在您的定义中,您将其设为 type a。那么,如何将 typea的值转换为 type 的值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

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

{-# LANGUAGE ScopedTypeVariables #-}

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


以上是Haskell:在类型类中定义变量的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>