[英]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 .)
或使用(->) r
的Functor
實例:
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")
一定會讓你的朋友大吃一驚。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.