簡體   English   中英

如何組合鏡片和仿函數?

[英]How do I combine lenses and functors?

我正在嘗試習慣Haskell的lens庫,發現自己在一些簡單的問題上苦苦掙扎。 例如,讓我們說(為方便起見) at_1具有以下類型(這至少是我理解它們的方式):

at :: Ord k => k -> Lens' (Map k v) (Maybe v)

_1 :: Lens' (a, b) a

如何將這些鏡頭組合成以下類型的鏡頭:

maybeFst :: Ord k => k -> Lens' (Map k (a, b)) (Maybe a)

你喜歡像鏡頭一樣

Lens' (Maybe (a, b)) (Maybe a)

但不能完全成為一個Lens ,因為放回Nothing影響b為好。 它可以是一個Getter

getA :: Getter (Maybe (a, b)) (Maybe a)
getA = to (fmap fst)

但是當你編寫它時,你最終也會得到一個Getter ,而不是一個完整的Lens

maybeFst :: Ord k => k -> Getter (Map k (a, b)) (Maybe a)
maybeFst k = at k . getA

可能更好的是使用Traversal代替

maybeFstT :: Ord k => k -> Traversal' (Map k (a, b)) a
maybeFstT k = at k . _Just . _1

這將允許你既得到(使用previewtoListOf )和設定值在fst地圖中的值,但你不能修改它是否存在於地圖:如果值不存在可以不加如果確實存在,則無法將其刪除。


最后,我們可以陪審一個具有適當類型的偽Lens ,盡管我們必須給它一個b的默認值

getA :: b -> Lens' (Maybe (a, b)) (Maybe a)
getA b inj Nothing       = (\x -> (,b) <$> x) <$> inj Nothing
getA _ inj (Just (a, b)) = (\x -> (,b) <$> x) <$> inj (Just a)

但請注意,它有一些不太像Lens行為。

>>> Just (1, 2) & getA 0 .~ Nothing & preview (_Just . _2)
Nothing

>>> Nothing & getA 0 .~ Just 1
Just (1,0)

所以經常最好避免使用這些假象來防止意外事故。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM