【发布时间】:2021-04-22 04:57:18
【问题描述】:
给定一个由多个映射组成的记录,我如何编写一个遍历(或棱镜,或Lens' TestLens (Maybe Interim))来将查找分组在一起?
首先,我目前的尝试。
data TestLens = TL
{ _foo1 :: Map.Map Text Int
, _foo2 :: Map.Map Text Bool
, _foo3 :: Map.Map Text Text
} deriving Show
tl = TL (Map.fromList [("a", 5), ("b", 6), ("c", 1), ("d", 3)])
(Map.fromList [("b", True), ("c", False), ("d", True)])
(Map.fromList [("c", "foo"), ("d", "bar")])
makeLenses ''TestLens
data Interim = Interim Int Bool Text deriving Show
data Interim2 = Interim2 Int Bool deriving Show
getOnePart s l k = s ^. l . at k
interim s k = Interim <$> getOnePart s foo1 k <*> getOnePart s foo2 k <*> getOnePart s foo3 k
interim2 s k = Interim2 <$> getOnePart s foo1 k <*> getOnePart s foo2 k
doTestStuff = tl ^.. folding (\s -> mapMaybe (interim s) (Map.keys $ s ^. foo1))
预期的行为是interim(就目前而言,它是镜头和..不是镜头的混搭)结合at多个Maps:
interim tl "a" = Nothing
interim tl "c" = Just (Interim 1 False "foo")
然后我可以折叠所有可能的键以获得Interims 的完整列表。
我想做的是在所有可能的Interims 上建立一个索引遍历(而不是一个未索引的折叠),但到目前为止我在itraversed我的组合中没有运气需要在这里..我怀疑是因为我在map 和lens 之间切换:
itraverseInterim2s = ...
> tl ^@.. itraverseInterim2s
[("b", Interim2 6 True), ("c", Interim2 1 False), ("d", Interim2 3 True)]
-- and if we assume there exists _1 :: Lens' Interim2 Int
> tl & itraverseInterim2s . _1 %~ (+5)
TL (Map.fromList [("a", 5), ("b", 11), ("c", 6), ("d", 8)])
(Map.fromList [("b", True), ("c", False), ("d", True)])
(Map.fromList [("c", "foo"), ("d", "bar")])
我无法确定是否通过制作Lens' TestLens (Maybe Interim2)、k -> Prism' TestLens Interim2(我认为其中只有一个满足镜头定律)或使用itraverseInterim2s . index k 遍历单个元素来更好地解决最后一个行为。
显然,对于每个InterimX ADT,我希望能够从fooX 映射的组合中提取我将不得不编写小样板,但这一点很好。
【问题讨论】:
标签: haskell traversal haskell-lens lenses