【问题标题】:Haskell: Defining a variable inside a typeclassHaskell:在类型类中定义变量
【发布时间】:2021-01-02 02:17:42
【问题描述】:

我是 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

我应该用什么替换 maxvalue = maxvalue :: a 以便 "(Maybe a).maxvalue == a.maxvalue" ?

【问题讨论】:

  • (另见Bounded 类型类)
  • 写InstanceSigs会有帮助。 Int 实例具有类型签名 maxvalue :: Int。 Maybe a 实例具有签名 maxvalue :: Maybe a。

标签: haskell


【解决方案1】:

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

首先,要实际解决问题,您需要认识到在您的Maxable 实例中Maybe a,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 构造函数来解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多