你希望像
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)
所以最好避免這些假牙來防止事故發生。
謝謝,我現在看到我所要求的類型永遠不可能是鏡頭! :) – wen
最後一點,如果我們有'Iso'(a,b)a'(這顯然是不可能的,那麼我們可以使用'映射ourIso :: Iso'(Maybe(a,b)) )'代替'getA'。也就是說,嘗試'fl(a,b)=(b,a)'用'flipP = iso fl fl',然後'maybeFlip k = at k。映射flipP :: Ord k => k - > Lens'(Map k(a,b))(Maybe(b,a))'。 –
只是一個小小的澄清:你的第一個例子不能成爲鏡頭的原因是你不能發明一個'b'放入'Nothing'時試圖放入'Just a',反過來就好了,這是我的嘗試:'不可能:: Lens'(Maybe(a,b))(也許a);' '不可能k(Just(a,b))= fmap(,b)<$> k(Just a);' '不可能k nothing = fmap(,undefined)<$> k Nothing'。 '不可能k沒有=沒有<$ k沒什麼',但是這不符合鏡頭法則。 – Hjulle