13

私はいくつかのデータ型を持っています

data Outer = Outer { _list :: [ Inner ] }
data Inner = Inner { _bool :: Bool }

Control.Lens を使用すると、次のように i 番目のインナー ('State Outer' モナド内) の _bool にアクセスできます。

boolValue <- gets (^. list . to (!! i) . inner)

この値を次のようなもので更新できるようにしたいと思います

list ^. (to (!! i)) ^. inner %= True

ただし(私の理解では)、「to」関数はゲッターを作成するだけであり、ゲッターまたはセッターとして使用できる真のレンズではありません。

では、(!! i) をレンズに変換して、このフィールドを更新できるようにするにはどうすればよいでしょうか?

4

2 に答える 2

17

(!!)a 以外のレンズのようなものに変えることはできません* Getter-- しかし、この種のことを行う関数があります: ix、インデックスで物事にアクセスするためのものです。これは実際には aTraversalではなくLens-- ここでは、失敗する可能性があることを意味します (インデックスが範囲外の場合) -- しかし、インデックスがリストにある限り、機能します。

ただし、別の問題があります --(^.)も、値を取得するためだけに使用される演算子です。(%=)これは、最初の引数としてレンズのようなものを取るeg と互換性がありません。And:(%=)既存の値に関数をマッピングするためのものです。設定するだけの場合は、 を使用できます(.=)。したがって、おそらく次のようなものが必要です。

list . ix i . inner .= True

* 実際にこれを実行できる関数がありますがupon、これは素晴らしい邪悪な黒魔術を使用するため、少なくともこの目的では (そしておそらく実際のコードでは) 使用しないでください。

于 2013-06-09T05:33:26.000 に答える
9

指定されたリスト要素へのelementである を使用します。Traversal

list . element i . inner %= True :: Outer -> Outer

リスト要素を取得したい場合はMaybe、リスト要素が存在しない可能性があるため、 a を使用して取得する必要があります。

myList :: Outer

myList ^? list . element i . inner :: Maybe Bool
于 2013-06-09T05:26:30.937 に答える