将Int定义为Haskell中类型类的实例时的问题

问题描述 投票:3回答:1

我正在尝试将Int定义为我的类型类Add的实例。我想定义自己的运算符+++,该运算符应在整数和字符串上重载。我的目标是能够使用相同的运算符添加整数并连接字符串。因此,我使用实例AddInt创建了类型类[char]

class Add a where
    (+++) :: a -> a -> a

instance Add Int where
    x +++ y = x + y

instance Add [char] where
    x +++ y = x ++ y

问题:在计算表达式1 +++ 2时,GHCi给我以下错误消息:

<interactive>:9:1: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
      prevents the constraint ‘(Show a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        ...plus 22 others
        ...plus 18 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In a stmt of an interactive GHCi command: print it

但是将Integer定义为Add的实例时

instance Add Integer where
    x +++ y = x + y

GHCi可以将1 +++ 2评估为3,但我没有收到错误。

问题:使用Int作为实例时,为什么不起作用?使用IntInteger有什么区别?

haskell types instance typeclass
1个回答
7
投票

鉴于它适用于Integer,但不适用于Int,我很确定这是由于“类型默认值”所致。

在GHCi中(在较小程度上在编译的代码中),如果表达式的类型不明确,则编译器将尝试几种“默认类型”,其中的默认值为Integer(但not Int) 。几乎可以肯定这就是差异的来源。

我怀疑如果在表达式的末尾添加:: Int,它将很好地执行。问题不是存在类型error,而是可能存在多个类型,并且编译器不确定您打算使用哪种类型。

我从未尝试过,但是我相信您可以通过说default (Int, Double)之类的内容来更改默认值。 (通常是default (Integer, Double)。)我认为这是正确的语法。不确定100%。

GHCi手册中对此有一些说明:https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#type-defaulting-in-ghci

还有Haskell报告:https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3(第4.3.4节)

© www.soinside.com 2019 - 2024. All rights reserved.