私はlensを初めて使用し、このstate0からnew_state2への変換と同等の2つの「セッター」操作を作成したいと思います。
let new_state1 = field1 %~ (const newVal1) $ state0
let new_state2 = field2 %~ (const newVal2) $ new_state1
これを行うための構文は何ですか?
面白いことに、レンズは関数と同じように構成されてい(.)
ます。
setterAB :: Lens' A B
setterBC :: Lens' B C
setterAC = setterAB . setterBC
ただし、あなたの例では、レンズを作成する必要はありません。変換(レンズと実際の操作の両方)を作成する必要があります。これを行うには2つの方法があります。
ああ、実際にそれに到達する前(.~)
に、(%~)
( "modify")の代わりに( " set")を使用して、コードを少し単純化しましょう。
let new_state1 = field1 .~ newVal1 $ state0
let new_state2 = field2 .~ newVal2 $ new_state1
&
かなりうまく機能する派手な演算子があります。それはただflip ($)
:
let new_state1 = state0 & field1 .~ newVal1
let new_state2 = new_state & field2 .~ newVal2
つまり、次のように書くことができます。
let new_state =
state0
& field1 .~ newVal1
& field2 .~ newVal2
さらに良いことに、実際にState
どこかにいる場合は、その通過を完全に取り除き、それをモナドに入れることができます。
let new_state = (flip execState state0) $ do
field1 .= newVal1
field2 .= newVal2
それらはで定義されているMonadState
ので、モナドスタックにいる場合は、そのインスタンスを直接使用するかStateT
、セッターがより多くのエフェクトを利用できるようにするために使用できます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加