簡體   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