5

私はレンズを試してみたかったのですが、Monocle ライブラリは (私の初心者の観点からは) これらの空想的なボイラープレートのないすべてのものに適しているように見えました@Lenses。残念ながら、初心者向けの学習教材はほとんどまたはまったくないことがわかりました (バニラ Scala の FP の基本は知っていますが、Scalaz は知りません)。公式のチュートリアルには簡単な例 (および/またはその結果) がなく、非常に複雑な Scalaz ライブラリが混在しています。マップへのアクセスなどの簡単なタスクは、最初のページで説明されると思われます。

次のスニペットがあります。

  @Lenses case class House(presentsDelivered: Int)

  type Houses = Map[(Int, Int), House]

  @Lenses case class Town(houses: Houses)

  @Lenses case class Santa(x: Int, y: Int)

  @Lenses case class World(santa: Santa, town: Town)

私はatとを見ましindexたが、単純な例はありません (applyOptionalボイラープレートが必要な奇妙な [私にとっての魔法] の答えだけです)。housesで地図を更新したいTown。私はこの精神で何かを試みていました:

(World.town ^|-> Town.houses ^|-> index((x, y)) ^|-> House.presentsDelivered)
  .modify { _ + 1 }(world)

これは構文的に間違っていますが、私がやりたかったことは明らかだと思います(指定された座標での変更)presentsDelivered。私の質問は、マップにアクセスするためにパーツを変更する方法ですか?Housex, yindex

ヘルプ、手がかり、初心者向けの学習教材のヒントは大歓迎です。

4

1 に答える 1

9

あなたはソリューションから文字通り1文字(そしておそらくインポート)離れています:

import monocle.function.all.index
import monocle.std.map._

(
  World.town              ^|->
  Town.houses             ^|-?
  index((0, 0))           ^|->
  House.presentsDelivered
).modify(_ + 1)

^|->インデックスの直前のを に置き換えたことに注意してください^|-?。これが必要なのは、ケース クラス メンバーの他のマクロ生成レンズとindex((x, y))は根本的に異なるためです。World.townそれらは値を指すことはできませんindexが、マップ内の指定されたインデックスに値がない場合は失敗する可能性があります。モノクルのタイプに関してindex((x, y))は、 はOptional[Houses, House]であり、World.townLens[World, Town]です。

オプショナルはある意味でレンズよりも弱く、一度オプショナルでレンズを組むと、それ以上レンズを組んでもオプショナルは続きます。したがって、次のレンズです。

World.town ^|-> Town.houses

ただし、これはオプションです。

World.town ^|-> Town.houses ^|-? index((0, 0)) ^|-> House.presentsDelivered

Monocle は一貫しx ^|-> yて、さまざまなタイプのx(レンズ、オプション、トラバーサルなど) をレンズでx ^|-? y構成し、さまざまなxをオプションで構成するために使用します。個人的には、演算子がややこしくcomposeLenscomposeOptional、 などを好みますが、好みはさまざまです。演算子を覚えたい場合は、少なくとも一貫して使用されていることを確信できます。必要な演算子を知る必要があるだけです。特定のタイプ。

コードのもう 1 つの潜在的な問題は、次のように記述できないことです。

import monocle.function.all.index

val houses: monocle.Optional[Houses, House] = index((0, 0))

これは、インデックスを作成する型の型クラスindexのインスタンスを必要とするため、単独ではコンパイルされません(この場合は . Monocle は機能するマップの汎用インスタンスを提供しますが、それをインポートする必要があります:IndexMap[(Int, Int), House]

import monocle.std.map._

申し訳ありませんが、学習教材について非常に良い提案はありませんが、ここでいつでも質問できます。Monocle Gitter チャンネルはかなり活発です。

于 2015-12-09T18:10:16.133 に答える