如果值类型不是单子,使用 lens 在状态单子内访问数组元素的推荐方式是什么?
以下代码将无法编译,因为 lens 不知道如何处理给定索引 i
处没有元素的情况。
type MyArray = Array Int Char
-- accessElemInStateWrong :: Int -> State MyArray Char
-- accessElemInStateWrong i = use $ ix i
通过将Control.Monad.State.Class
中的gets
与Control.Lens.Fold
中的preview
结合使用,可以实现一个工作版本。
accessElemInState :: Int -> State MyArray (Maybe Char)
accessElemInState i = gets $ preview $ ix i
这很好运作。然而,鉴于lens定义的丰富函数和运算符,我惊讶地发现似乎没有特别针对此情况的函数。
因此,我的问题是:lens是否定义了类似于gets . preview
的函数?如果没有,实现accessElementInState
的推荐方法是什么?
我提出这个问题的原因是因为lens
在状态单子之外定义了一个特殊的运算符。虽然以下代码由于相同的原因无法编译。
-- accessElemWrong :: Int -> MyArray -> Char
-- accessElemWrong i a = a ^. ix i
我们可以使用操作符
(^?)
将结果包装在Maybe
中并进行安全查找。accessElem :: Int -> MyArray -> Maybe Char
accessElem i a = a ^? ix i
use $ ix i
不起作用?错误信息是什么? - Joachim BreitnerChar
没有Monoid
实例。如果元素类型是一个 Monoid 并且我们试图访问一个缺失的元素,那么 lens 将返回mempty
。然而,由于Char
没有 Monoid 实例,因此 lens 不知道在这种情况下该怎么做。 - Lemming