【发布时间】:2020-05-14 22:56:30
【问题描述】:
关于Functors 的这两条规则相当有名:
- 如果类型参数以逆变方式出现,则无法创建
Functor - 任何类型最多有一个有效的
Functor实例
但如果你稍微作弊,你就可以打破第一条规则。以休斯列表为例:
data HList a = UnsafeHList ([a] -> [a])
pattern HList a <- UnsafeHList (($ []) -> a)
where HList a = UnsafeHList (a ++)
instance Functor HList where
fmap f (HList a) = HList (map f a)
-- instances necessary to make HList useful, but irrelevant to this example, have been omitted
只要您假设所有HLists 都将通过智能构造函数生成,那么Functor 实例是合法的,即使a 出现逆变。
我的问题:你可以使用类似的技术来打破第二条规则吗?如果您假设它们总是通过智能构造函数生成,是否有任何类型具有两个不同的有效 Functor 实例?
【问题讨论】:
-
(ehem) 顺便说一句,你可以通过使用米田来制作差异列表功能而不作弊:
newtype HList a = HList (forall b. (a -> b) -> [b] -> [b]) -
@luqui 那似乎确实有效并且具有良好的渐近性。我想知道为什么与智能构造方法相比,它没有更受欢迎。
-
(co)yoneda 是一个很好的将事物功能化的技巧,被低估了。也许是因为它有一个可怕的名字(以前从未阻止过我们......)
标签: haskell constructor typeclass functor parametric-polymorphism