我正在尝试了解下面的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
为什么类型s
和a
不在问题之上的类型b
?
答案 0 :(得分:9)
你试图表达这个:
f :: a -> ∃s . s
...但是你写的签名实际上是
f :: a -> ∀s . s
所有这些意味着什么?
∃s . s
表示,这些函数可能会返回某种类型的值,即“存在类型s
,以便该函数返回一个s
值。。这是Haskell语言不支持的,因为它结果证明是没用的。∀s . s
表示该函数能够生成任何类型的值,即“适用于所有类型s
,该函数可以返回s
值“。后者非常有用; fmap
实际上是一个很好的例子:无论a
和b
是什么类型,该函数都有效,并且用户始终保证结果实际上具有所需类型,即{ {1}}。
但这意味着您不能像在f b
中那样在实现中选择某种特定类型。 ......好吧,实际上你可以这样做,但只能将存在主体包装在数据类型中:
String
...但正如我所说,这几乎完全无用,因为当有人想要使用那个实例时,他们无法知道包装结果值具有什么特定类型。对于完全未知类型的值,你无能为力。