如果值类型不是monoid,则使用lens访问状态monad中数组元素的推荐方法是什么?
以下将无法编译,因为如果给定索引i
中没有元素,镜头不知道该怎么做。
type MyArray = Array Int Char
-- accessElemInStateWrong :: Int -> State MyArray Char
-- accessElemInStateWrong i = use $ ix i
可以通过将来自gets
的Control.Monad.State.Class
与来自preview
的Control.Lens.Fold
相结合来实现工作版本。
accessElemInState :: Int -> State MyArray (Maybe Char)
accessElemInState i = gets $ preview $ ix i
这很好用。然而,鉴于镜头所定义的过多功能和操作员,我惊讶地发现这个特殊情况似乎没有。
所以,我的问题是:镜头定义像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