「Scalaに存在演算子を求めるのは間違っているだろうか」をLens/Prismで解いてみる
元の記事はこちらです。
Scalaに存在演算子を求めるのは間違っているだろうか - だいたいよくわからないブログ
TL眺めてたらがくぞさんが
Lens の匂いを感じる http://t.co/KGFPNSLSP2
— がくぞ (@gakuzzzz) 2015, 7月 15
ってpostしてて「あ!このデータ構造、Lensのサンプルで見たことあるやつだ!」 が再生されたので(?)、やってみました。
もちろんScalaでLensといえばMonocleだよね!!*1
前置き
その1
何も考えずに各case classに対してLensを定義してやってみます。
ちなみに、&<-?はapplyPrism、^|->はcomposeLens、^<-?はcomposePrismのエイリアスメソッドです。
このsomeはmonocle.std.option#someで、Monocle標準で提供してるPrismです。
b.valueがOption[A]なので、a.valueする為にOption[A] => Aが必要だったので使用しています。
結果は以下の通り。
scala> Example1.good
res0: Option[Int] = Some(1)
scala> Example1.bad
res1: Option[Int] = None
良さそうですね。
その2
some分冗長な気がしたので、_bと_dをPrismにしてみます。
これでsomeがなくなった分短く書けるようになりました。
もちろん、同じ結果が得られます。
scala> Example2.good
res2: Option[Int] = Some(1)
scala> Example2.bad
res3: Option[Int] = None
まとめ
どちらにせよCoffeeScriptっぽく書けるわけでもなく、@xuwei-k さんの
「Scalaに存在演算子を求めるのは間違っているだろうか」の解答例 - scalaとか・・・
val x: Option[Int] = OptValue(edcba).wrap._value._fuga._hoge._bar._foo
みたいな感じでOptionを意識することなく繋げることは出来ませんでした。 とはいえ、macroもType Dynamicも使ってない*2ので、それなりにシンプルにかけてるはず...
もっと短くカッコよく書ける方法があれば教えて下さい!!
おまけ
コードの表現的に負けてしまった(?)ので、Lens/Prismを使ったメリットを挙げておくと
のようにgetだけでなくsetやmodifyもできるようになります。やったぜ!