为什么我不能让String成为一个类型类的实例? [英] Why can I not make String an instance of a typeclass?
问题描述
data Foo =
FooString String
...
class Fooable a where - (这是一个很好的方法来命名这个吗?)
toFoo :: a - > Foo
我想让字符串
一个实例 Fooable
:
instance Fooable String其中
toFoo = FooString
GHC然后抱怨:
<$ p $对于`Fooable String'非法的实例声明
(所有的实例类型都必须是这样的形式(T t1 ... tn)
其中T不是同义词
在'Fooable String'的实例声明中使用-XTypeSynonymInstances。)
如果我使用 [Char]
:
实例Fooable [Char]其中
toFoo = FooString
GHC抱怨:
`Fooable [Char]'
的非法实例声明(所有实例类型都必须是(T a1 ... an)
其中a1 ... an是类型变量*,
,每个类型变量最多出现一次立场头。
如果您想禁用它,请使用-XFlexibleInstances。)
在`Fooable [Char]'的实例声明中
问题:
- 为什么我不能让字符串和实例typeclass?
- 如果我添加一个额外的标志,GHC似乎愿意让我逃避这一切。这是一个好主意吗? / code>只是
[Char]
的类型别名,它只是类型构造函数 []
类型为 Char
,所以这将是([] Char)
的形式。它不是(T a1 .. an)
形式,因为 Char
不是一个类型变量。 这个限制的原因是为了防止重叠的情况。例如,假设您有一个实例Fooable [Char]
,然后有人过来并定义了一个实例Fooable [a]
。现在编译器将无法确定你想使用哪一个,并会给你一个错误。
通过使用 -XFlexibleInstances
,你基本上承诺编译器不会定义任何这样的实例。
根据你想要完成的工作,定义一个包装可能会更好:
newtype Wrapper = Wrapper字符串
实例Fooable Wrapper其中
...
Given:
data Foo =
FooString String
…
class Fooable a where --(is this a good way to name this?)
toFoo :: a -> Foo
I want to make String
an instance of Fooable
:
instance Fooable String where
toFoo = FooString
GHC then complains:
Illegal instance declaration for `Fooable String'
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Fooable String'
If instead I use [Char]
:
instance Fooable [Char] where
toFoo = FooString
GHC complains:
Illegal instance declaration for `Fooable [Char]'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are type *variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Fooable [Char]'
Question:
- Why can I not make String and instance of a typeclass?
- GHC seems willing to let me get away with this if I add an extra flag. Is this a good idea?
This is because String
is just a type alias for [Char]
, which is just the application of the type constructor []
on the type Char
, so this would be of the form ([] Char)
. which is not of the form (T a1 .. an)
because Char
is not a type variable.
The reason for this restriction is to prevent overlapping instances. For example, let's say you had an instance Fooable [Char]
, and then someone later came along and defined an instance Fooable [a]
. Now the compiler won't be able to figure out which one you wanted to use, and will give you an error.
By using -XFlexibleInstances
, you're basically promising to the compiler that you won't define any such instances.
Depending on what you're trying to accomplish, it might be better to define a wrapper:
newtype Wrapper = Wrapper String
instance Fooable Wrapper where
...
这篇关于为什么我不能让String成为一个类型类的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!