与fmap具有相同多态类型的函数是否必须等于fmap?

Zac*_*Zac 4 haskell functor

我正在阅读《 Haskell编程》第二版,并且遇到了这句话:

...只有一种方法可以使任何给定的参数化类型成为函子,因此具有相同多态类型的任何函数都fmap必须等于fmap

不过,这对我来说似乎不对。我可以看到每种类型只有一个有效的定义,但是可以肯定的是,我可以用这种类型定义不相同的任意数量的函数吗?fmapFunctor(a -> b) -> f a -> f b

为什么会这样呢?或者,这仅仅是作者的一个错误?

lef*_*out 9

您误解了作者在说什么。

......与任何功能相同的多态类型fmap ...

这意味着带有签名的任何功能

Functor f => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

必须等价于fmap。(当然,除非您允许最低值。)

这个说法是正确的;如果您尝试定义这样的函数,就可以很容易地看到它:因为f除了它是一个函子之外,您一无所知,因此获得非函数的唯一方法是?f b价值是通过映射f a一个。

引号中的逻辑含义不太明确:

只有一种方法可以将任何给定的参数化类型转换为函子,因此,与fmap具有相同多态类型的任何函数都必须等于fmap。

我认为是作者的手段有,因为一个Functor f => (a -> b) -> f a -> f b函数必然调用fmap,因为fmap始终是唯一的一个参数化类型的有效的仿函数映射,任何Functor f => (a -> b) -> f a -> f b确实会在实践中也服从法律函子,也就是说,它会 fmap

我同意“因此”的措词有点不好,但原则上引用是正确的。