在状态 monad 中使用 lens 访问数组元素

Array element access with lens in the state monad

在状态中访问数组元素的推荐方法是什么 如果值类型为 lens 的 monad 不是幺半群。

下面会编译不通过,因为lens不知道如果 给定索引 i.

处没有元素
type MyArray = Array Int Char
-- accessElemInStateWrong :: Int -> State MyArray Char
-- accessElemInStateWrong i = use $ ix i

一个工作版本可以通过组合 gets 来自 Control.Monad.State.Classpreview 来自 Control.Lens.Fold

accessElemInState :: Int -> State MyArray (Maybe Char)
accessElemInState i = gets $ preview $ ix i

这很好用。然而,考虑到过多的函数和运算符 镜头定义,我惊讶地发现似乎没有 对于这种特殊情况。

所以,我的问题是:lens 是否定义了类似 gets . preview 的东西?而如果 不是,推荐的实施方式是什么 accessElementInState?


我问的原因是因为 lens 确实定义了一个特殊的运算符 在状态 monad 之外。虽然以下内容不会编译相同 原因如上

-- accessElemWrong :: Int -> MyArray -> Char
-- accessElemWrong i a = a ^. ix i

我们可以使用运算符 (^?) 将结果包装在 Maybe 中并执行安全 查找。

accessElem :: Int -> MyArray -> Maybe Char
accessElem i a = a ^? ix i

有一个函数 preuse 听起来正是您要找的:

accessElemInState :: Int -> State MyArray (Maybe Char)
accessElemInState i = preuse $ ix i

-- or
accessElemInState = preuse . ix