如何解决为什么即使我不应用 f 参数,我也需要在 fmap 的定义中再次调用构造函数?
我不知道为什么下面的 fmap _ a = a
是非法的。代码如下:
data Sum a b = First a | Second b
instance Functor (Sum a) where
fmap f (Second b) = Second (f b)
fmap _ (First a) = First a
fmap _ a = a -- Why can't I do this instead?
另一个问题是,这会影响性能还是只在编译时发生?
解决方法
关于性能:在编译过程的后期,当 GHC 删除了大部分类型信息时,最好注意何时像这样重构值。这一步捕获了很多情况,但不是全部;有时代码会以这样的方式进行转换,以至于重构不再明显。
,您需要调用构造函数 anew 来创建一个 new 值,因此它的类型将与您开始使用的类型不同。
fmap :: (b -> c) -> Sum a b -> Sum a c
fmap (f :: b -> c) :: Sum a b -> Sum a c
fmap (f :: b -> c) (x :: Sum a b) -> Sum a c
a :: a a :: a
First a :: Sum a b First a :: Sum a c
b :: b c :: c
Second b :: Sum a b Second c :: Sum a c
给定 a :: a
,First a
的类型为 Sum a t
,其中 t
由 First a
出现的上下文决定。等号两边的两个 First a
定义了两个不同的值,每个值都有自己的类型。使用右侧的变量 a
,它仍然引用与左侧相同的 Sum a b
类型的值。但是我们需要一个不同的类型,根据 fmap
。
不能这样做的原因是,fmap
的结果类型取决于 f
的结果类型,而表达式 a
不依赖。也就是说,您没有约束 f b ~ a
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。