2015-12-09 7 views
5

レンズを試したかったのですが、Monocleライブラリは、私のnoobishの視点から見れば、それらの派手なボイラープレートなしのものすべてにぴったりでした。@Lenses残念ながら、私は初心者のための学習教材がほとんどないことを知っています(私はScalazのバニラScalaのFPの基礎を知っています)。公式チュートリアルでは、簡単な例(および/またはその結果)と、非常に複雑なScalazライブラリのミックスが欠けています。 Mapへのアクセスのような簡単な作業は、最初のページでカバーされると想定します。私はatindexを見Monocleでマップを変更する

@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) 

が、ない簡単な例(applyOptionalとのちょうどいくつかの奇妙な[私のための魔法]答えは決まり文句を必要としないもの):

は、私は次のスニペットを持っています。私はhousesの地図をTownに更新したいと思っています。

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

文法的に間違っているが、私はそれは私が(指定x, y座標にHousepresentsDeliveredを変更)やりたいことは明白だと思う:私はこの精神で何かをしようとしていました。だから私の質問は、indexの部分を変更しての部分にアクセスするには?

ヘルプ、手がかり、または教師に優しい学習教材のヒントを歓迎します。

+1

ドキュメントの不足で申し訳ありませんが、私たちはゆっくりと作業しています。一眼レフにポップアップしたり、ここで質問をしたり、ギブスで質問したりしてください。 –

答えて

7

あなたは文字通り離れて溶液から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はマップ内の指定されたインデックスに値がないと失敗する可能性があります。 Monocleのタイプに関しては、index((x, y))Optional[Houses, House]であり、World.townLens[World, Town]です。

オプションはレンズよりも弱いですし、オプションでレンズを作ってしまえば、さらに多くのレンズを作っても引き続きオプションがあります。したがって、次のレンズである:

World.town ^|-> Town.houses 

しかし、これはオプションである:

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

モノクルは、一貫してレンズをx(レンズ、optionals、トラバースなど)の種類を構成するx ^|-> yを使用して、そしてxを別のものと組み合わせて構成するのはx ^|-? yです。私は個人的にオペレータが少し混乱し、composeLenscomposeOptionalなどを好みますが、好みは異なります。オペレータを覚えておきたい場合は、少なくとも一貫して使用されていると確信できます。所与のタイプの必要性。

あなたのコードと他の潜在的な問題は、あなただけの、この書き込みができないことである:indexは、そのタイプのIndex型クラスのインスタンスを必要とするので、これは自分自身でコンパイルされません

import monocle.function.all.index 

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

をそれは、この場合Map[(Int, Int), House]で(にインデックス付けますモノクルが動作するマップのための一般的なインスタンスを提供していますが、それをインポートする必要があります。

import monocle.std.map._ 

私はlearninのための任意のひどく良い提案を持っていない怖いですあなたはいつもここで質問をすることができ、Monocle Gitter channelはかなり活発です。

+0

誠実で正確な回答をいただきありがとうございます。正直言って、私は答えを得ることについてあまり楽観的ではありませんでした。単なるMonocleライブラリの人気度はわかりませんが、tag [tag:monocle-scala]は2桁でさえありませんでした。私は間違っていたことがうれしいです、明日私はそれらの[クリスマスパズル](http://adventofcode.com/)を解決するいくつかの楽しみを持っているつもりです:)。 – monnef

関連する問題