如果索引列表遍历不匹配,则返回“Nothing”
我是新手lens并试图使用它来对嵌套结构进行许多小的修改,这可能会失败并可能返回额外的结果:
element -> Maybe element
element -> Maybe (result, element)
如何通过 index修改内部结构,Nothing如果索引不存在也返回?如果我使用traverseOf+ ix:
type Thing = (String, [Int])
exampleThing :: Thing
exampleThing = ("example", [0, 1])
predMaybe :: Int -> Maybe Int
predMaybe x
| x == 0 = Nothing
| otherwise = Just (pred x)
decrementThingAt :: Int -> Thing -> Maybe Thing
decrementThingAt i = traverseOf (_2 . ix i) predMaybe
> decrementThingAt 1 exampleThing
Just ("example",[0,0])
> decrementThingAt 0 exampleThing
Nothing
然后,如果索引不存在,则默默地返回未修改的结构:
> decrementThingAt 2 exampleThing
Just ("example",[0,1])
而我也想回到Nothing这里。如果可能的话,我想在镜头组合的“内部”进行。我知道我可以使用preview/ ^?“outside”Maybe根据光学器件是否与任何目标匹配来获得:
> preview (_2 . ix 1) exampleThing
Just 1
> preview (_2 . ix 2) exampleThing
Nothing
但我希望能够写出类似. 我看到一些在“外面”做的尴尬的方法,比如:traverseOf (_2 . ix i . previewed) predMaybefoldMapOf
decrementThingAt i = getFirst . foldMapOf (_2 . ix i) (First . predMaybe)
但是有没有办法让所有东西都在同一个管道中,这样我就不会重复/明确地拆卸和重新组装结构?
我也不太明白如何将它与返回额外的结果结合起来。目前我正在使用StateT并且zoom喜欢这样:
import Control.Lens (_1, zoom)
import Control.Monad.Trans.State (StateT, runStateT)
import Data.List (uncons)
-- NB: uncons :: [a] -> Maybe (a, [a])
pop :: Thing -> Maybe (Char, Thing)
pop = runStateT $ zoom _1 $ StateT uncons
> pop exampleThing
Just ('e',("xample",[0,1]))
> pop ("", [0, 1])
Nothing
但是我仍然不知道如何使用缺少的索引来实现它,例如,type ThingMaybe = (Maybe String, [Int])如果Maybe是Nothing.