简体   繁体   English

类型类定义中的抽象数据类型

[英]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? 当类型ab不在时,为什么类型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? 所有这些意味着什么?

  • The existential type ∃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值”。
    This is not supported by the Haskell language, because it turns out to be pretty useless. Haskell语言不支持这种做法,因为事实证明这种做法毫无用处。
  • The universal type ∀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实际上是一个很好的例子:无论ab是什么类型,该函数都有效,并且用户始终保证结果实际上具有所需的类型,即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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM