如果数组和索引都处于State状态,则使用镜头进行数组索引

时间:2014-12-02 09:04:46

标签: arrays haskell lens

我在状态monad中有一个数组和一个数组索引。我可以使用use读取idx并使用+=和其他类似修饰符对其进行修改:

{-# 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

现在我想将arridx合并为arr[idx]形成一个镜头:

combo arr idx = undefined

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

我该怎么做? Data.Sequence的代码会有所不同吗?

1 个答案:

答案 0 :(得分:0)

答案结果只是

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

由于索引可能超出范围,ix是一个名为Traversal的部分镜头。因此bar必须使用uses而不是use

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

由于偏好,ii也是Monoid m => m Int而不是Int

如果需要返回Int的原始不安全行为,可以将uses替换为unsafeUses traversal = (^?! traversal) <$> get

来恢复