应用两个 Folds 或 Getters 并且只有在两者都成功时才成功
Apply two Folds or Getters and only succeed when both succeed
假设我有以下列表:
lst :: [(Bool, Maybe Integer)]
lst = [(True, Just 3), (True, Nothing), (False, Just 12)]
使用lens库,想提取元组的元素,但只希望第二个元素为Just
时成功。我想要一些光学器件,split
可以像这样工作:
> lst ^.. folded.<i>split</i> (_1.to not) (_2._Just)
[(False, 3), (True, 12)]
我可以这样实现 split
自己:
split :: Getting (First a) s a -> Getting (First b) s b -> Fold s (a, b)
split a b = folding (\x -> (,) <$> (x ^? a) <*> (x ^? b))
…这似乎有效。但是,这似乎我必须重新发明轮子。镜头库是否已经提供了一些以同样好的方式完成此任务的东西?
aside
组合器采用 Prism
作用于元组的第二个组件,returns Prism
作用于整个元组:
ghci> lst ^.. folded.aside _Just
[(True,3),(False,12)]
得到的棱镜在组件匹配时匹配,否则失败。
将其与 to
和 bimap
相结合,我们可以重现您的示例:
ghci> lst ^.. folded.aside _Just.to (bimap not id)
[(False,3),(True,12)]
要处理第一个组件,我们可以使用 swapped
:
ghci> [(Just 3,False)]^..folded.swapped.aside _Just.swapped
[(3,False)]
假设我有以下列表:
lst :: [(Bool, Maybe Integer)]
lst = [(True, Just 3), (True, Nothing), (False, Just 12)]
使用lens库,想提取元组的元素,但只希望第二个元素为Just
时成功。我想要一些光学器件,split
可以像这样工作:
> lst ^.. folded.<i>split</i> (_1.to not) (_2._Just)
[(False, 3), (True, 12)]
我可以这样实现 split
自己:
split :: Getting (First a) s a -> Getting (First b) s b -> Fold s (a, b)
split a b = folding (\x -> (,) <$> (x ^? a) <*> (x ^? b))
…这似乎有效。但是,这似乎我必须重新发明轮子。镜头库是否已经提供了一些以同样好的方式完成此任务的东西?
aside
组合器采用 Prism
作用于元组的第二个组件,returns Prism
作用于整个元组:
ghci> lst ^.. folded.aside _Just
[(True,3),(False,12)]
得到的棱镜在组件匹配时匹配,否则失败。
将其与 to
和 bimap
相结合,我们可以重现您的示例:
ghci> lst ^.. folded.aside _Just.to (bimap not id)
[(False,3),(True,12)]
要处理第一个组件,我们可以使用 swapped
:
ghci> [(Just 3,False)]^..folded.swapped.aside _Just.swapped
[(3,False)]