Reputation: 4205
What is the recommended way to access an element of an array within the state monad with lens if the value type is not a monoid.
The following will fail to compile, because lens doesn't know what to do if
there is no element at the given index i
.
type MyArray = Array Int Char
-- accessElemInStateWrong :: Int -> State MyArray Char
-- accessElemInStateWrong i = use $ ix i
A working version can be implemented by combining gets
from
Control.Monad.State.Class
with preview
from Control.Lens.Fold
.
accessElemInState :: Int -> State MyArray (Maybe Char)
accessElemInState i = gets $ preview $ ix i
This works just fine. However, given the plethora of functions and operators that lens defines, I was surprised to find that there doesn't seem to be one for this particular case.
So, my question is: Does lens define something like gets . preview
? And if
not, what's the recommended way to implement accessElementInState
?
The reason why I'm asking is because lens
does define a special operator
outside of the state monad. While the following will not compile for the same
reason as above.
-- accessElemWrong :: Int -> MyArray -> Char
-- accessElemWrong i a = a ^. ix i
We can use the operator (^?)
to wrap the result in a Maybe
and perform safe
lookup.
accessElem :: Int -> MyArray -> Maybe Char
accessElem i a = a ^? ix i
Upvotes: 3
Views: 875