将 Int 定义为类型 class in Haskell 的实例时出现问题
Problem when defining Int as an instance of a type class in Haskell
我正在尝试将 Int
定义为我的类型 class Add
的实例。
我想定义我自己的运算符 +++
,它应该在整数和字符串上重载。我的目标是能够使用相同的运算符添加整数和连接字符串。因此我用实例 Int
和 [char]
:
创建了类型 class Add
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
作为实例时不起作用?使用 Int
或 Integer
有什么区别?
鉴于它适用于 Integer
但不适用于 Int
,我相当确定这是由于 "type defaulting".
在 GHCi 中(在较小程度上在编译代码中),如果一个表达式具有不明确的类型,编译器会尝试几个 "default types",其中 Integer
(但 不是 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 节)
我正在尝试将 Int
定义为我的类型 class Add
的实例。
我想定义我自己的运算符 +++
,它应该在整数和字符串上重载。我的目标是能够使用相同的运算符添加整数和连接字符串。因此我用实例 Int
和 [char]
:
Add
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
作为实例时不起作用?使用 Int
或 Integer
有什么区别?
鉴于它适用于 Integer
但不适用于 Int
,我相当确定这是由于 "type defaulting".
在 GHCi 中(在较小程度上在编译代码中),如果一个表达式具有不明确的类型,编译器会尝试几个 "default types",其中 Integer
(但 不是 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 节)