「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もできるようになります。やったぜ!