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. 然后,它对您感到困惑,因为虽然它知道a是Maxable(因为您在实例上下文中这么说),但它不知道a1是Maxable。
为了在这种情况下获得更好的错误消息,您可以ScopedTypeVariables通过添加启用 GHC 扩展
{-# LANGUAGE ScopedTypeVariables #-}
到文件的顶部。如果你用这个语言扩展运行你当前的代码,你会得到一个不同的错误,GHC 抱怨它a不等于Maybe a. 如上所述,这可以通过使用Just构造函数来解决。