[英]Eliminating `flip` in Haskell lens
I'm trying to get the hang of lenses.我正在尝试掌握镜头的窍门。 Is there a more idiomatic way to write the following?
有没有更惯用的方式来编写以下内容? (placeholders preceded by underscores)
(下划线前面的占位符)
flip (set _lens) _a . fmap _f
To me, the use of flip
seems to suggest non-idiomatic code.对我来说,使用
flip
似乎暗示了非惯用代码。 Is there a better combinator that avoids flip
in this situation?在这种情况下是否有更好的组合器可以避免
flip
? Is there a more lens-like way of integrating the fmap?
是否有更类似于镜头的方式来集成
fmap?
In this case, you might want to consider writing it pointed在这种情况下,您可能要考虑将其写成指向
\x -> _a & _lens .~ fmap _f x
which feels much more idiomatic to me.这对我来说更加地道。
If you really want it pointfree without flip
, you can convert the above to pointfree:如果你真的想要它没有
flip
的无点,你可以将上面的转换为无点:
(_a &) . set _lens . fmap _f
(Although technically, since &
is equivalent to flip ($)
, you're really just hiding the flip
.) (虽然从技术上讲,因为
&
等同于flip ($)
,所以你实际上只是隐藏了flip
。)
I think @DDub has covered the first half of your question.我认为@DDub 已经涵盖了您问题的前半部分。 As for a more "lens-like" way of integrating the
fmap
, this seems to be a special case of a more general problem.至于集成
fmap
的更“类似镜头”的方式,这似乎是更普遍问题的特例。 If I have a setter:如果我有一个二传手:
> (1,"a") & _1 .~ True
(True,"a")
then I think there ought be a combinator that allows me to write:那么我认为应该有一个组合器可以让我写:
> (1,"a") & _1 . applying not .~ True
(False,"a")
This combinator doesn't appear to exist in lens
(unless someone else can spot it), but you can define it as:该组合器似乎不存在于
lens
中(除非其他人可以发现它),但您可以将其定义为:
applying :: Functor f => (a -> b) -> (c -> f a) -> (c -> f b)
applying f = (fmap f .)
or using the Functor
instance for (->) r
:或使用
(->) r
的Functor
实例:
applying :: Functor f => (a -> b) -> (c -> f a) -> (c -> f b)
applying = fmap . fmap
This leads to the amusing fact that the setter:这导致了一个有趣的事实,即 setter:
_lens . (fmap . fmap . fmap) _f
combines _lens
with application of fmap _f
, so the following produce equivalent results:将
_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")
and are sure to amaze your friends.一定会让你的朋友大吃一惊。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.