每个镜头都是一次穿越……怎么样?

问题描述 投票:0回答:2

Control.Lens.Tutorial 说:

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'
?然而,本教程得出了相反的结论。

haskell functor applicative haskell-lens
2个回答
10
投票

A

Lens'
适用于 all 函子,其中包括所有应用函子,因此如果
f
Lens'
,则
f
也是
Traversal'

A

Traversal'
适用于所有应用函子,但不一定适用于所有函子。因此,如果
g
Traversal'
,则它不一定是
Lens'

(我不是正式描述这一点的人,但至少对我来说,看起来这些类型在其约束中是“逆变”的。

Lens'
Traversal'
的子类型,正是因为
Functor
Applicative
的超类。)


0
投票

我通常不喜欢可爱的“现实世界实体”类比,但通过考虑以下示例,这个问题可能会变得更清楚:

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
的子类型。佐伊可以很好地照顾宠物,她可以喂养任何狗以及狮子。但彼得没有这样的资格,他只能处理无害的宠物。因此,正是因为他被限制在更具体的动物类别中,所以他本人是比专门的动物园管理员更普遍的人的成员。

© www.soinside.com 2019 - 2024. All rights reserved.