2

レンズについては、まだ完全には理解できていません。

applicationState = (
    'a',
    'b',
    (   M.fromList $ zip [1..3]  [11,22,33],
        M.fromList $ zip [4,5,6] [44,55,66],
        M.fromList $ zip [7,8,9] [M.fromList $ zip [2,3,4] ["77","777","7777"],
        M.fromList $ zip [2,3,4] ["88","888","8888"],
        M.fromList $ zip [2,3,4] ["99","999","9999"]] )
    )

これを行うためのよりレンズの慣用的な方法はありますか:

λ> view (_3 . _3 . at 9) applicationState >>= view (at 4) >>= return . ('9':)
Just "99999"
4

1 に答える 1

2

使用traverse :: Traversal (Maybe a) (Maybe b) a bしてから使用できますpreview

preview (_3 . _3 . at 9 . traverse . at 4 . traverse . to ('9':)) applicationState

なぜならix i = at i . traverse、これは次のようにも書けるからです。

preview (_3 . _3 . ix 9 . ix 4 . to ('9':)) applicationState

そのように変更することもできますが、atのいずれかが失敗した場合、何も変更されません ( を使用してマップに新しい要素を挿入することはできませんTraversal)。


別の方法は、を使用することnon :: a -> Lens' (Maybe a) aです。これは、最初のマップ ( lens によってアクセスされる_3._3) に値として空のマップが含まれておらず、2 番目のマップに値として空の文字列が含まれていない場合にのみ機能します。したがって、次の値は applicationState では無効になります。

('a', 'b', 
  ( M.fromList $ zip [1..3] [11,22,33]
  , M.fromList $ zip [4,5,6] [44,55,66]
  , M.fromList $ zip [7..9] [M.empty] -- No value of this map may be the empty map
  )
)

を使用nonすると、例は次のように記述できます。

view (_3 . _3 . at 9 . non M.empty . at 4 . non "" . to ('9':)) applicationState

これにより、設定を介して新しいエントリを挿入したり (設定した場合、キー 4 または 9 がまだ存在しない場合は作成されます)、エントリを削除したり (値 "" に設定すると、キー 4 が削除されます) も可能になります。そのキーを削除した後にマップが空の場合、キー 9 も削除されます)。

于 2014-07-09T12:00:10.753 に答える