type Traversal' a b = forall f . Applicative f => (b -> f b) -> (a -> f a) type Lens' a b = forall f . Functor f => (b -> f b) -> (a -> f a)
请注意,Lens' 和 Traversal' 之间的唯一区别是类型类约束。 “镜头”具有函子约束,“遍历”具有应用约束。这意味着任何 Lens' 也自动成为有效的 Traversal'(因为 Functor 是 Applicative 的超类)。
我根本不遵循这里的逻辑顺序。我们知道每个
Applicative
都是一个Functor
。由此看来,是否应该得出(如果有的话)每个Traversal'
都是一个Lens'
?然而,本教程得出了相反的结论。
A
Lens'
适用于 all 函子,其中包括所有应用函子,因此如果 f
是 Lens'
,则 f
也是 Traversal'
。
A
Traversal'
适用于所有应用函子,但不一定适用于所有函子。因此,如果 g
是 Traversal'
,则它不一定是 Lens'
。
(我不是正式描述这一点的人,但至少对我来说,看起来这些类型在其约束中是“逆变”的。
Lens'
是Traversal'
的子类型,正是因为Functor
是Applicative
的超类。)
我通常不喜欢可爱的“现实世界实体”类比,但通过考虑以下示例,这个问题可能会变得更清楚:
class Animal a where feed :: a -> ArmouredGlove -> IO String
instance Animal Cat where feed _ _ = print "Miaow"
instance Animal Dog where feed _ _ = print "Woof"
instance Animal Lion where feed _ _ = print "Rwaaar"
class Animal a => Pet a where cuddle :: a -> UnprotectedHand -> IO String
instance Pet Cat where cuddle _ _ = print "Purr"
instance Pet Dog where cuddle _ _ = print "Yawn"
type PetOwner = ∀ a . Pet a => a -> IO String
type ZooWarden = ∀ a . Animal a => a -> IO String
peter :: PetOwner
peter = \pet -> cuddle pet Peter'sHand
zoey :: ZooWarden
zoey = \animal -> feed animal Zoey'sGlove
这里,
ZooWarden
是PetOwner
的子类型。佐伊可以很好地照顾宠物,她可以喂养任何狗以及狮子。但彼得没有这样的资格,他只能处理无害的宠物。因此,正是因为他被限制在更具体的动物类别中,所以他本人是比专门的动物园管理员更普遍的人的成员。