[英]Abstract data types in a type class definition
I'm trying to understand what's happening with the type s
below: 我试图了解下面的类型
s
发生了什么:
class A a where
f :: a -> s
data X = X
instance A X where
f x = "anything"
I expected this to work, thinking that since type s
isn't bound to anything, it could be anything. 我希望这可以工作,认为因为类型
s
不受任何约束,它可以是任何东西。 But the compiler says that it "Couldn't match expected type 's' with actual type '[Char]'", as if type s
was a fixed type like Int, Char… 但是编译器说它“无法将预期类型'与实际类型'[Char]'匹配”,好像类型
s
是固定类型,如Int,Char ...
So my second interpretation was to say that, since we don't know anything about s
in the type class declaration, we cannot tell when making X
an instance of A
if the return value of the function f
we give matches type s
or not. 所以我的第二种解释就是说,因为我们对类型类声明中的
s
一无所知,如果我们给出的函数f
的返回值与s
类型匹配,我们无法判断何时使X
成为A
的实例。 But there are type classes that use abstract data types that are not bound to anything without problems, like Functor: 但是有些类使用的抽象数据类型没有绑定到任何没有问题的东西,比如Functor:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Why is the type s
above a problem when types a
and b
here aren't? 当类型
a
和b
不在时,为什么类型s
出现问题?
You're trying to express this: 你试图表达这个:
f :: a -> ∃s . s
...but what the signature you've written says is actually ......但你写的签名实际上是什么
f :: a -> ∀s . s
What does all of that mean? 所有这些意味着什么?
∃s . s
∃s . s
∃s . s
means, the functions may return a value of some type , ie “there exists a type s
such that the function returns an s
value”. ∃s . s
意味着,函数可以返回某种类型的值,即“存在类型s
,使得函数返回s
值”。 ∀s . s
∀s . s
∀s . s
means, the function is able to produce a value of any type , ie “for all types s
, the function can return an s
value”. ∀s . s
表示该函数能够生成任何类型的值,即“对于所有类型s
,函数可以返回s
值”。 The latter is very useful; 后者非常有用;
fmap
is actually a good example: that function works, no matter what types a
and b
are, and the user is always guaranteed that the result will actually have the desired type, namely fb
. fmap
实际上是一个很好的例子:无论a
和b
是什么类型,该函数都有效,并且用户始终保证结果实际上具有所需的类型,即fb
。
But that means you can't just pick some particular type in the implementation, like you did with String
. 但这意味着您不能像在
String
那样在实现中选择某种特定类型 。 ...Well, actually you can do that, but only by wrapping the existential in a data type: ......好吧,实际上你可以这样做,但只能将存在主体包装在一个数据类型中:
{-# LANGUAGE ExistentialQuantification, UnicodeSyntax #-}
data Anything = ∀ s . Anything s
class A a where
f :: a -> Anything
instance A X where
f x = Anything "anything"
...but as I said, this is almost completely useless, because when somebody wants to use that instance they'll have no way to know what particular type the wrapped result value has. ...但正如我所说,这几乎完全无用,因为当有人想要使用该实例时,他们无法知道包装结果值具有什么特定类型。 And there is nothing you can do with a value of completely unknown type.
对于完全未知类型的值,你无能为力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.