我正试着习惯 lens
Haskell的库,发现自己在一些简单的问题上苦苦挣扎。例如,让我们说(为方便起见) 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
Haskell的库,发现自己在一些简单的问题上苦苦挣扎。例如,让我们说(为方便起见) 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
可能比这更好的是使用a 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)
所以经常最好避免这些假象来防止意外事故。
你喜欢像镜头一样
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
可能比这更好的是使用a 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)
所以经常最好避免这些假象来防止意外事故。