これ
ドワンゴScala勉強会で学んだ、ハイブリッド言語「Scala」の魅力
twitterでつぶやいたけど
さっきのあれによりPhantomTypeについて考えなおしているが、やっぱりなんかモヤモヤするなぁ。フィールド全部変えるならべつにPhantomTypeじゃなくて違うClassのインスタンスでいいし、implicit使わないんだったらScala以外でもできるしだいぶ違うものな気が
2011-12-06 22:46:15 via web
そして、例が謎ぃので 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 とは結構違う仕組みになるはずです。
あと、そもそも
っていう点に議論の余地があると思います。ここは自分も頭の中整理できなくて、うまく説明できないのですが・・・
なんだかサンプルコードなくて説明が雑ですが、今の自分の理解はこんな感じです。理解が深まって、また書きたいことができたら 追記 or 別で書くかもしれません(´・ω・`)