在monad状态下使用镜头访问数组元素

问题描述 投票:3回答:1

如果值类型不是monoid,则使用lens访问状态monad中数组元素的推荐方法是什么?

以下将无法编译,因为如果给定索引i中没有元素,镜头不知道该怎么做。

type MyArray = Array Int Char
-- accessElemInStateWrong :: Int -> State MyArray Char
-- accessElemInStateWrong i = use $ ix i

可以通过将来自getsControl.Monad.State.Class与来自previewControl.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
haskell lens
1个回答
2
投票

有一个功能preuse听起来就像你正在寻找的:

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

-- or
accessElemInState = preuse . ix
© www.soinside.com 2019 - 2024. All rights reserved.