在Haskell Programming From First Principles第 16.13 节中,展示了Wrap数据类型以演示其 Functor 实例需要对其参数之一进行类型类约束的类型:
data Wrap f a =
Wrap (f a)
deriving (Eq, Show)
在为 (Wrap f) 演示了几个不正确的 Functor 实例之后,显示了一个正确的实例:
instance Functor f => Functor (Wrap f) where
fmap g (Wrap fa) = Wrap (fmap g fa)
这个类型类实例应该可以工作的事实对我来说似乎是正确的。事实上,GHC 毫无怨言地接受了它。
为了说服自己需要“Functor f”约束,我尝试在没有它的情况下创建自己的类型类实例。我的方法侧重于模式匹配,在没有 fmap 的情况下以“仿函数”的方式使用 f,类似于本书前面介绍的方法。这是尝试:
instance Functor (Wrap f) where
fmap g (Wrap (f a)) = Wrap f (g a)
当我将它加载到 GHCi 中时,我收到以下错误:
Prelude> :l 16.12-wrap.hs
[1 of 1] Compiling Main ( 16.12-wrap.hs, interpreted )
16.12-wrap.hs:10:17: error: Parse error in pattern: f
|
10 | fmap g (Wrap (f a)) = Wrap f (g a)
| ^^^
Failed, no modules loaded.
有人可以解释我尝试的实例的问题吗?在我看来,GHC 有足够的信息从顶部的 Wrap 定义中推断出 f 是一种 (* -> *),所以我不明白为什么我的尝试没有解析。