「Scalaに存在演算子を求めるのは間違っているだろうか」の解答例


なにやってるんだ・・・、と思いつつ見てたら、とりあえず解答を思いついてしまったので貼っておきます。

Scalaに存在演算子を求めるのは間違っているだろうか


ちなみに、あくまで解答"例"であって、他にも色々方法あるかもしれません。

ちゃんと調べきれてないので確証が全く無いのですが、「Type Dynamicによるメソッド呼び出しのselectDynamicへの変換」と「implicit classによる暗黙の型変換」は両立しないみたい・・・?

はい、自分の知る限り両立しないです。なので、方針を説明すると

  • 最初の一回だけ明示的にDynamic用のオブジェクトにラップする処理を書く
  • _valueとかを呼び出したら、OptionではなくDynamic用のオブジェクトにラップしたまま返す
  • あと、valueに限らないものができたので、 _valueでなくても _hoge でも、むしろアンダースコアなしでもいいようになった
  • Dynamicなオブジェクトから最後にOptionに戻すのには、これも明示的に書いてもいいけど、この場合の逆の変換はimplicit conversionでもできるので定義しておく
  • Option[A] と Option[ Option[A] ] でラップ用オブジェクトわけるの難しいというか、逆に面倒なので、ラップ用オブジェクトは1つにして、全部マクロで頑張る

というわけで、こうなりました


追加でScalaのマクロ的なことを含め、自分のコードを説明すると

  • どうせwhitebox使ってるんだし、最初からselectDynamicの型はAnyにしてしまった(Anyのサブタイプ == 任意の型を返す、ということ)
  • Optionがネストしてるのかしてないのかは、頑張ってマクロで判断してるわけだが、その部分かなり雑なので、もっと綺麗な書き方ありそう。バグも色々残ってそう
  • 色々チェックをサボってるので、よくも悪くも、Option以外でも、mapやflattenを持ってると呼び出せてしまうはず?

ところでマクロの練習としては面白いけど、実用するにはどう考えてもマクロやDynamicの間違った使い方な感じしかしないので、やめたほうがいいですね・・・。