Scala の Phantom Type について

これ

ドワンゴScala勉強会で学んだ、ハイブリッド言語「Scala」の魅力

twitterでつぶやいたけど

そして、例が謎ぃので Java で書いてみたら書けちゃったんだけれどもェ・・・(´・ω・`)

追記:
kmizuさんにこんなコメントもらいました

そうですね、重要な点書き忘れてましたね。この例が良くない点として、
Normalizedな状態のVectorでも、もう一度normalizeというメソッドが呼べちゃう(そしてそれは、generalized type constraints使えば防げる)ということです。showNormalの引数には制約かけることができているけれど、normalizeというメソッドは、どちらの状態でも呼べてしまいますよね。normalizeした状態のものにもう一度normalize呼ぶってそもそもありえなくて、それ呼んだあとの状態ってどういうオブジェクト?ってなってあばばばばばばば(・ω・`)

自分が知ってる限り phantom type って foursqure の Rogue っていうライブラリが有名なのですが(他に例を知っていたら教えて下さい)
追記:
ライブラリとしては、Rogueが有名ですが、この方法というか概念は以下のblogのほうが先ですかね、たしか
http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html
上記のblogは2008年なので、当時version2.8が出る前のはずで、case classのcopyメソッドがなかったことも考慮しないといけませんが。
type safe builderとなっているので、type safe builderとphantom typeと色々用語でてきちゃってう〜ん(´・ω・`)
それらの用語の(細かい違いがあるのならば?)違いを説明したい・・・けど、そんな能力は今のところ自分にはないので、リンクを貼っておくだけにします


で、Rogueですが、以下の公式の engineer blog に説明載っていたり、slideshare にも色々あります。

http://engineering.foursquare.com/2011/01/21/rogue-a-type-safe-scala-dsl-for-querying-mongodb/
http://engineering.foursquare.com/2011/01/31/going-rogue-part-2-phantom-types/

http://www.slideshare.net/jorgeortiz85

まぁこれ読めばいいわけですが、phantom type って implicit parameter で generalized type constraints を組み合わせないとあまり意味ない*1気がするんですがどうなんでしょう? phantom type のちゃんとした定義は無いかと思うんですが・・・

ちなみに、generalized type constraints っていうのは =:= とか

  • あるclassのインスタンスの状態を、型(パラメータ)で表したい
  • (上記で自分が書いたコードのように)Javaでも型パラメータで状態を表すことだけならできる・・・?
  • 型パラメータで状態を表すということはつまり
    • あるクラスのインスタンス内部の状態をちょっとだけ変更し
    • 同時に型パラメータも変更した、新しい別のインスタンスを作成して返す必要がある

その際に case class での copy メソッドを使うことにより、とても短く書ける!

という点です。


もう一点重要な点として、 case class の copy メソッドを使って、copyの処理を名前渡しで書いておけば、あとから case class の メンバーが増えても copy の処理の部分のコードは変える必要がない という点です。


Javaだとそれができないはず・・・ですよね?なにか親クラスを作っておいて継承したり、内部class作っておいてゴニョゴニョすれば、
"一部の field の値を変えた新しいインスタンスを作成する処理"
をちょっと簡単に書ける仕組みはつくれるとは思いますが、 Scalaでの case class の copy とは結構違う仕組みになるはずです。


あと、そもそも

  • 型パラメータで状態を表すべきなのか?
  • そもそも意味が違うのならば、単に型パラメータを変えたインスタンスをつくるのではなく、異なる class のインスタンスとして表すべきではないのか?

っていう点に議論の余地があると思います。ここは自分も頭の中整理できなくて、うまく説明できないのですが・・・

なんだかサンプルコードなくて説明が雑ですが、今の自分の理解はこんな感じです。理解が深まって、また書きたいことができたら 追記 or 別で書くかもしれません(´・ω・`)

*1:generalized type constraintsはJavaだとできない・・・はず