29

私が知っているのは、一方が機能し、もう一方が機能しないということだけです。

コンテキスト:別のデータ構造へのFを含む 1 つのデータ構造があります。私の目標は、与えられたとのフィールドを記述するを構築することでした。Data.Map.Map k SSLensFkS

問題は、キーkがマップに存在しない可能性があることです。関数がその戻り値を Maybe でラップできることは問題ありません。ただし、を使用して Maybe を介してレンズを伝播できませんでしたat。多くのスタック オーバーフローの回答を読んだ後、私はこれに出くわしました

に置き換えるatix、型の問題が解決たことがわかりまし(^.)(^?)

Question: It seems like at and ix do the same thing, at least with regard to Map. Both take a key and give a 'Lens' to the value at that key. However, ix seems to play nice with the function composition operator (.). What is the difference between the two?


Off Topic Rant:

I like infix operators as much as the next guy but the Control.Lens package seems to have gone a little overboard. For a new user having some English names and a key somewhere would lower the learning curve. Due to the huge number of wrapper classes used in the Lens library it is particularly difficult to dig through the type signatures if you don't already know what is going on. My code is starting to look like Perl for heaven sake.

4

1 に答える 1

25

これらの関数を含むクラスの利用可能なインスタンスを見ると、 と の違いはすでに顕著atです。ix

  • のインスタンスAt: Map、IntMap、HashMap
  • のインスタンスIxed: [a]、Map、ByteString、Text、その他多数

すべてのインスタンス ifAtは のインスタンスでもありますが、 のすべてのインスタンスが のインスタンスでもあるIxわけではありません。IxAt

それで、それらの違いは何ですか?Atコンテナに存在しないキーを挿入できるコンテナ用です。これはマップでは明らかに可能ですが、たとえばリストでは不可能です。リストにインデックスを付けてそこにあるアイテムを変更できるようにするにIxは、新しいアイテムを作成することはできませんが、存在しないキーに書き込もうとすると「何もしません」。

>>> Data.Map.fromList [('a', 1)] & at 'b' .~ Just 4 
fromList [('a',1),('b',4)] -- Inserts value 
>>> Data.Map.fromList [('a', 1)] & ix 'b' .~ 4  
fromList [('a',1)]          -- Does nothing because key is not present

a .~ Just b( 、のショートカットもありますa ?~ b)

ix技術的には、この違いはがTraversalatであるのに対してLensであるという事実から来ています。そしてat、レンズは「多分何か」を「返す」ものなので、単なる「何か」だけを撮るレンズでは構成できません。ixは 0 または 1 の値を持つトラバーサルであるため、他のトラバーサルと同じように ix を構成できます ( と書けるのと同じようにtraverse . traverse)。(^?)そのトラバーサルの最初の値 (頭) を取るだけです。

いつでも次から派生できixますat

ixAt = at . traverse

同じ定義がすでに lens(<.)にありますが、合成でインデックスを at から保持するために使用しています。(atixは両方ともインデックス付きレンズ/トラバーサルです)。

トピック外: lens のほとんどの演算子にも中置名があります。(不完全な) 表はhttps://github.com/ekmett/lens/wiki/Operatorsにあります。

于 2013-08-24T02:20:36.590 に答える