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

时间:2017-10-12 15:48:59

标签: haskell

我正在尝试了解下面的s类型发生了什么:

class A a where
    f :: a -> s

data X = X

instance A X where
     f x = "anything"

我希望这可以工作,认为由于类型s没有绑定任何东西,它可能是任何东西。但编译器说它“无法将预期类型'与实际类型'[Char]'匹配”,好像类型s是固定类型,如Int,Char ......

所以我的第二个解释就是说,因为我们在类型类声明中对s一无所知,所以我们无法判断何时X成为A的实例我们给出的函数f的返回值是否与s匹配。但是有些类型使用的抽象数据类型没有任何问题,例如Functor:

class Functor f where
    fmap :: (a -> b) -> f a -> f b 

为什么类型sa不在问题之上的类型b

1 个答案:

答案 0 :(得分:9)

你试图表达这个:

    f :: a -> ∃s . s

...但是你写的签名实际上是

    f :: a -> ∀s . s

所有这些意味着什么?

  • 存在类型 ∃s . s表示,这些函数可能会返回某种类型的值,即“存在类型s,以便该函数返回一个s值。。这是Haskell语言不支持的,因为它结果证明是没用的。
  • 通用类型 ∀s . s表示该函数能够生成任何类型的值,即“适用于所有类型s,该函数可以返回s值“。

后者非常有用; fmap实际上是一个很好的例子:无论ab是什么类型,该函数都有效,并且用户始终保证结果实际上具有所需类型,即{ {1}}。

但这意味着您不能像在f b中那样在实现中选择某种特定类型。 ......好吧,实际上你可以这样做,但只能将存在主体包装在数据类型中:

String

...但正如我所说,这几乎完全无用,因为当有人想要使用那个实例时,他们无法知道包装结果值具有什么特定类型。对于完全未知类型的值,你无能为力。