如果索引列表遍历不匹配,则返回“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])如果MaybeNothing.

以上是如果索引列表遍历不匹配,则返回“Nothing”的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>