この広告は、90日以上更新していないブログに表示しています。2014の22日目です。日付変わっちゃいました、すみません。今回はちょっとMonocle触ってみました。Truffaut氏がメインで開発してるScalaでLensなライブラリです。現在)で、つい先日リリースされたばかりのピチピチです。2014もともとはHaskellのLensパッケージがあって、それをScalaで実装してみたみたいな感じです。Isoを提供していて、今回はその中からLensとPrismを紹介します。あと、Lensに関しては圏論的なバックグラウンドがあるそうですが全然詳しくないのでこの記事では触れないことにします。Lensはどういう時に欲しくなるのかLensはJavaなどで言うgetterやsetterを抽象化した概念で、不変性を保ちつつネストしたデータ構造に対するアクセスをLensの合成で表現できるようにしたものになります。いう事か見ていきましょう。公式READMEのサンプルをちょいとお借りして、下記のようなネストしたデータ構造があったとします。classであればcopyメソッドを使うのがいいでしょう。))おっと、不変性を保ったばかりにとても冗長なコードになってしまいました。ちなみにvarだった場合はご想像の通りさっきのコードに比べてすっきりかけます。Employee(Company(Address(Street(Chuodori))))ちょいと長いので二行に分けちゃいましたが、copyメソッドを使ってた時よりも遥かにすっきり直感的です。あぁ...これでは「varで良くね?」って言われても返す言葉がありません.....。不変性を保ちつつ上記varの時と同様にすっきりかけないものでしょうか.....。!ここでLensの出番です!!MonocleでLensまずは、対象のデータに対してLensを定義してやる必要があります。MonocleでのLensの定義方法は以下の3種類です。アノテーションを使うではそれぞれ試してみましょう。※Lensの定義はREPL上ではできないのでsbtにMonocleの依存追加してcompileしてやります。対象のデータに対するgetterとsetterを引数に渡します。console'でREPLを立ち上げて実行してみましょう。Employee(Company(Address(Street(Chuodori))))これが冒頭で言っていた「データに対するアクセスをLensの合成で表現できる」って話です。ちなみに「composeLens」のエイリアスとして「^|->」が定義されているので7文字分すっきりできます。Lenserマクロを使うv0.5.1より追加された機能です。手動で定義するよりも簡単にLensを定義してやることができます。手動で明示的に定義した場合と同じなので省略します。@Lensesアノテーションを使うもっとも簡単にLensを「生成」してやる方法です。classの宣言に対して@Lensesアノテーションをつけると各変数に対してLensが定義されます。Company)}ただし、この方法を使うには色々注意が必要です。class(ライブラリの方で定義されてるものなど)に使えなかったりします。一応、実験的な機能と捉える方がいいでしょう。2と同じですが、Lensの生成先がコンパニオンオブジェクト内なのでちょっと面倒になります。Employee(Company(Address(Street(Chuodori))))Prismもあるんだよ?さて、冒頭で述べましたが、Monocleが提供してるのはLensだけではありません。Prismもその一つです。Prismはざっくりイメージで言うと「失敗を表現できるようになったLens」です。*2実際のコード見てもらった方が早いですね。Lensの時と同様にPrismの定義はREPL上ではできないのでsbtにMonocleの依存追加してcompileしてやります。console'でREPLを立ち上げて試してみましょう。Empty()res2でtoIntに失敗した場合はEmpty()が帰ってきているのがわかります。ちなみに、以下のような使い方もできます。Stringをさせることができます。*4res13は内部的には"1"をIntに変換した後100を足して再度文字列にしています。何も知らずに見ると結構やばいですね。今回自分で上記のstrToIntを定義しましたが、Scalaの基本型に対するPrismは既にMonocle側で定義されてたりします。v1.0.1がリリースされました。その辺のハマりどころとか書いて「もうすぐリリースされるはずなので、1.x系の安定版を待ちましょう!!」みたいな感じで締めようと思ってたんですけど、そんな必要なくなっちゃいました。安心してv1.0.1を使いましょう!!とかいいつつ、まだまだ全然全く本当の美味さを把握できてる気がしないので引き続き試してみたいです、はい。あ、あとargonautの中でも使われていて面白そうなんですけど、全然追えてないのでまたの機会に。parameters.」とかってエラー吐く.....*2:概念的にはLensとPrismはそれぞれ別な方向へIsoを特化させたものであり、「Lensを拡張したのがPrismである」というわけではありません。Prismが実装されているのかって言うとそうでもないです。parameters」とかってエラー吐く.....*4:Prism定義時、第二引数に渡した関数が呼ばれてます。05:09MonocleとかいうのがありましてTweet広告を非表示にする関連記事2017-05-05退職しますちょっと数日たってしまいましたが、日記です。いい話...2015-12-23Platedとは何なのか?この記事はadventar版Scalaアドベントカレンダーの21日目です。...2015-12-18macro-compatを使ってmacroの互換性を簡単に管理するこの記事はadventar版Scalaアドベントカレンダーの17日目です。...2015-09-16MonocleとScalazにcontributeした話わざわざ丁寧に書く内容ではないよなーとか思ってたので書くつ...2015-07-15「Scalaに存在演算子を求めるのは間違っているだろうか」をLens/Prismで解いてみる元の記事はこちらです。»プロフィールid:Aoino新宿でScala書くお仕事してます。モナモナした話が大好きです。(3)はてなブログをはじめよう!Aoinoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。