繁体   English   中英

消除 Haskell 镜头中的“翻转”

[英]Eliminating `flip` in Haskell lens

我正在尝试掌握镜头的窍门。 有没有更惯用的方式来编写以下内容? (下划线前面的占位符)

flip (set _lens) _a . fmap _f

对我来说,使用flip似乎暗示了非惯用代码。 在这种情况下是否有更好的组合器可以避免flip 是否有更类似于镜头的方式来集成fmap?

在这种情况下,您可能要考虑将其写成指向

\x -> _a & _lens .~ fmap _f x

这对我来说更加地道。

如果你真的想要它没有flip的无点,你可以将上面的转换为无点:

(_a &) . set _lens . fmap _f

(虽然从技术上讲,因为&等同于flip ($) ,所以你实际上只是隐藏了flip 。)

我认为@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 .)

或使用(->) rFunctor实例:

applying :: Functor f => (a -> b) -> (c -> f a) -> (c -> f b)
applying = fmap . fmap

这导致了一个有趣的事实,即 setter:

_lens . (fmap . fmap . fmap) _f

_lensfmap _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")

一定会让你的朋友大吃一惊。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM