[英]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
這將允許你既得到(使用preview
或toListOf
)和設定值在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.