Haskell 中的非法实例声明
Illegal instance declaration in Haskell
我尝试了以下代码
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
instance Fractional a => Group a where
x .+. y = x + y
zero = 0 :: a
opposite = negate :: a -> a
但是在加载到 GHCi 时,出现以下错误:
group1.hs:11:26: error:
• Illegal instance declaration for ‘Group a’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Group a’
|
11 | instance Fractional a => Group a where
|
我做错了什么?
啊!我终于明白了,哪里不对。在 Haskell 中,只能为 ADT 实例化一个 class。因此,唯一合理的解决方案是声明如下内容:
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
newtype GroupType a = GroupType a
instance Fractional a => Group (GroupType a) where
GroupType x .+. GroupType y = GroupType $ x + y
zero = GroupType 0
opposite (GroupType x) = GroupType $ negate x
我能够编译你的例子:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
-- data Fractional a = Fractional a a
instance (Fractional a, Num a) => Group a where
x .+. y = x + y
zero = 0
opposite = negate
FlexibleInstances
允许具有约束的未知类型的实例。基本上允许instance X a
UndecidableInstances
我们需要,因为我们声明任何 a
属于 class Group
并且它可能(不可避免?)导致 a
属于Group
通过几个不同的 instance
声明。
我尝试了以下代码
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
instance Fractional a => Group a where
x .+. y = x + y
zero = 0 :: a
opposite = negate :: a -> a
但是在加载到 GHCi 时,出现以下错误:
group1.hs:11:26: error:
• Illegal instance declaration for ‘Group a’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Group a’
|
11 | instance Fractional a => Group a where
|
我做错了什么?
啊!我终于明白了,哪里不对。在 Haskell 中,只能为 ADT 实例化一个 class。因此,唯一合理的解决方案是声明如下内容:
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
newtype GroupType a = GroupType a
instance Fractional a => Group (GroupType a) where
GroupType x .+. GroupType y = GroupType $ x + y
zero = GroupType 0
opposite (GroupType x) = GroupType $ negate x
我能够编译你的例子:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class Group a where
(.+.) :: a -> a -> a
(.-.) :: a -> a -> a
zero :: a
opposite :: a -> a
x .-. y = x .+. opposite y
opposite x = zero .-. x
{-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}
-- data Fractional a = Fractional a a
instance (Fractional a, Num a) => Group a where
x .+. y = x + y
zero = 0
opposite = negate
FlexibleInstances
允许具有约束的未知类型的实例。基本上允许instance X a
UndecidableInstances
我们需要,因为我们声明任何a
属于 classGroup
并且它可能(不可避免?)导致a
属于Group
通过几个不同的instance
声明。