我认为@DDub 已经涵盖了您问题的前半部分。至于集成fmap 的更“类似镜头”的方式,这似乎是更普遍问题的特例。如果我有二传手:
> (1,"a") & _1 .~ True
(True,"a")
那么我认为应该有一个组合器可以让我写:
> (1,"a") & _1 . applying not .~ True
(False,"a")
此组合子似乎不存在于 lens 中(除非其他人可以发现它),但您可以将其定义为:
applying :: Functor f => (a -> b) -> (c -> f a) -> (c -> f b)
applying f = (fmap f .)
或将Functor 实例用于(->) r:
applying :: Functor f => (a -> b) -> (c -> f a) -> (c -> f b)
applying = fmap . fmap
这导致了一个有趣的事实,即 setter:
_lens . (fmap . fmap . fmap) _f
结合_lens 和fmap _f 的应用,所以下面的结果是一样的:
ex1 = (flip (set _1) ("a","b") . fmap not) $ Just True
ex2 = ("a","b") & _1 . applying (fmap not) .~ Just True
ex3 = ("a","b") & _1 . (fmap . fmap . fmap) not .~ Just True
-- all the above yield: (Just False,"b")
一定会让你的朋友大吃一惊。