Haskell: instances parameterized type 一种单一类型
Haskell: instances parameterized type one single type
我正在编写一些解析器代码,其中涉及参数化类型:
data Power i = Power1 { charges :: i } | Power2 { charges :: i }
我知道类型 i
将始终是 Int
(但已参数化,因为我需要它用于另一种类型 class)。
现在我想让我的 Power
类型从 Show
派生(以特定格式,所以我需要自己覆盖它)。据我所知,i
只会是 Int
,我试过:
instance Show (Power Int) where
show (Power1 0) = ""
show (Power1 i) = "some formatting involving i\n"
show (Power2 0) = ""
show (Power2 i) = "some other formatting involving i\n"
但是,这不会编译,并显示消息
• Illegal instance declaration for ‘Show (Power Int)’
(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 ‘Show (Power Int)’
|
22 | instance Show (Power Int) where
为什么这不可能?
为什么这与编译器相比如此不同?
instance (Show i) => Show (Power i) where
您不能对类型使用类型约束,但对类型 classes。在您的示例中,可以为 Integral
类型 class 实例化 Show。然后 show 被定义为 Power Int
和 Power Integer
.
instance Integral a => Show (Power a) where
show (Power1 0) = ""
show (Power1 i) = "some formatting involving i\n"
show (Power2 0) = ""
show (Power2 i) = "some other formatting involving i\n"
GHC 说 All instance types must be of the form (T a1 ... an) where a1 ... an are *distinct type variables*
。这是在 Haskell 98 中定义的。要将具有具体类型的数据类型作为 class 参数,需要 FlexibleInstances
扩展。因为存在包装实例问题。
例如:
newtype Foo a = Foo a
class Bar a where
baz :: a -> a
instance Bar (Foo Int) where
baz = ...
instance Show a => Bar (Foo a) where
baz = ...
当您调用 baz 1
时,编译器会混淆版本是否应该调用。 1
是Int
也属于Show
class!详情写在,大家有时间应该看看
我正在编写一些解析器代码,其中涉及参数化类型:
data Power i = Power1 { charges :: i } | Power2 { charges :: i }
我知道类型 i
将始终是 Int
(但已参数化,因为我需要它用于另一种类型 class)。
现在我想让我的 Power
类型从 Show
派生(以特定格式,所以我需要自己覆盖它)。据我所知,i
只会是 Int
,我试过:
instance Show (Power Int) where
show (Power1 0) = ""
show (Power1 i) = "some formatting involving i\n"
show (Power2 0) = ""
show (Power2 i) = "some other formatting involving i\n"
但是,这不会编译,并显示消息
• Illegal instance declaration for ‘Show (Power Int)’
(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 ‘Show (Power Int)’
|
22 | instance Show (Power Int) where
为什么这不可能?
为什么这与编译器相比如此不同?
instance (Show i) => Show (Power i) where
您不能对类型使用类型约束,但对类型 classes。在您的示例中,可以为 Integral
类型 class 实例化 Show。然后 show 被定义为 Power Int
和 Power Integer
.
instance Integral a => Show (Power a) where
show (Power1 0) = ""
show (Power1 i) = "some formatting involving i\n"
show (Power2 0) = ""
show (Power2 i) = "some other formatting involving i\n"
GHC 说 All instance types must be of the form (T a1 ... an) where a1 ... an are *distinct type variables*
。这是在 Haskell 98 中定义的。要将具有具体类型的数据类型作为 class 参数,需要 FlexibleInstances
扩展。因为存在包装实例问题。
例如:
newtype Foo a = Foo a
class Bar a where
baz :: a -> a
instance Bar (Foo Int) where
baz = ...
instance Show a => Bar (Foo a) where
baz = ...
当您调用 baz 1
时,编译器会混淆版本是否应该调用。 1
是Int
也属于Show
class!详情写在