Using lens for array indexing if both array and index are in State

血红的双手。 提交于 2019-12-13 02:21:30

问题


I have an array and an array index in a state monad. I can read idx using use and modify it using += and other similar modifiers:

{-# Language TemplateHaskell #-}
import Control.Lens
import Control.Lens.TH
import Control.Monad.State
import Data.Array

data M = M { _arr :: Array Int Int, _idx :: Int }

$(makeLenses ''M)

foo x = do
    idx += x
    ii <- use idx
    return ii

Now I want to combine arr and idx to form a lens to arr[idx]:

combo arr idx = undefined

bar x = do
    combo arr idx += x
    ii <- combo arr idx
    return ii

How can I do this? Will code be different for Data.Sequence?


回答1:


The answer turned out to be just

combo arr idx f m = (arr . ix (m^.idx)) f m

As the index may be out of bounds, ix is a partial lens called Traversal. So bar has to use uses instead of use:

foo x = do
    combo arr idx += x
    ii <- uses $ combo arr idx
    return ii

Also ii is Monoid m => m Int instead of Int, because of partiality.

If original unsafe behaviour of returning Int is needed it can be restored by replacing uses with unsafeUses traversal = (^?! traversal) <$> get



来源:https://stackoverflow.com/questions/27245512/using-lens-for-array-indexing-if-both-array-and-index-are-in-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!