在状态 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.Class
和 preview
来自 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
在状态中访问数组元素的推荐方法是什么 如果值类型为 lens 的 monad 不是幺半群。
下面会编译不通过,因为lens不知道如果
给定索引 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
这很好用。然而,考虑到过多的函数和运算符 镜头定义,我惊讶地发现似乎没有 对于这种特殊情况。
所以,我的问题是: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