Scala の CanBuildFrom などについて
あと、厳密に語るなら、構文、型システム、(実行時の)意味論、に分けて論じる必要がある。Scalaに関して言うと、構文と(実行時の)意味論は割と単純。型システムは「複雑」だけど、その「複雑さ」に出会うのは、主にライブラリ設計者であって、ふつーのユーザは型システムの暗黒面に
2011-07-03 11:30:43Stringを要素に持つ任意のコレクションにgrepを適用できるようにする - あるいはScalaの暗黒面について http://bit.ly/kGEbdK のエントリについて、補足を末尾に書いた。 #scala
2011-07-03 11:53:11このエントリで、Scalaの暗黒面に触れざるを得なかったのは、「戻り値同型の原則」を遵守するためであって、それを放り投げていいなら、別に難しくないよー、という補足です。 #scala
2011-07-03 11:53:58@nobsun まず、概念として複雑になります。利用者側はそれほど複雑なことを知らなくてもいいですが、汎用ライブラリ(目的が限定されているものは含まない、という意味です)の設計者は型システムに関する複雑な概念をある程度知っておく必要があります。 #scala
2011-07-03 12:06:14@lyrical_logical 私自身は難しいとは特に感じてませんです。ただ、 CanBuildFrom なんかよくわからない、と思っている方は結構居られそうなので、なんか書きました。
2011-07-03 13:33:17CanBuildFromを次のポストで140文字以内で説明してみるテスト。ただし、型パラメータ名From, Elem, Toはあらかじめ知っているものとする。 #scala
2011-07-03 13:52:11From型のコレクションから「Elemを要素型に持つTo型のコレクションを生成するためのビルダ」を生成するためのファクトリオブジェクト。以上。具体例が無ければ140文字以内でかけた。 #scala
2011-07-03 13:55:52具体例。 CanBuildFrom[List[Int], String, List[String]] 。List[Int] から、「List[String]を生成するためのビルダ」を生成するファクトリ。具体的なインスタンスは「勝手に湧いてくる」ので知らんでもいい #scala。
2011-07-03 14:01:18微妙な例。 CanBuildFrom[Map[Int, Int], Int, Map[Int, Int]]。 こんな型のインスタンスは勝手に湧いてきません(そういう風に作れるけど)。 #scala
2011-07-03 14:05:14CanBuildFrom[List[String], String, Set[String]] 。こういうのもデフォルトではだめ(自作すればいけるけど)。 #scala
2011-07-03 14:13:56// breakOutで適切なビルダを解決(後からtoSetよりパフォーマンス的にうれしい) import collection.breakOut val s: Set[String] = List("foo", "bar").map(identity)(breakOut)
2011-07-03 14:20:03結局、どういうときにCanBuildFromのインスタンスが「湧いてくる」かというと: "CanBuildFrom[C[A], B, D[B]] where D[B] >: C[A] (C, Dは任意のジェネリックなコレクション型)" が成り立つとき(例外あり)。 #scala
2011-07-03 14:22:14結構昔に、kaitenn さんが breakOut の使い方について何かコメントされていたはず。たしか、stack overflow の引用だったかな。
2011-07-03 14:22:42http://bit.ly/l7vsc4 でミス。"CanBuildFrom[C[A], B, D[B]] where D[B] >: C[B] (C, Dは任意のジェネリックなコレクション型)" が正しい。 #scala
2011-07-03 14:24:17ScalaのトレイトとかRubyのmix-inモジュールよりも、C# の拡張メソッド(実体はただのstaticメソッド)が好きな自分はstaticおじさんと呼ばれてしまうのだろうか。
2011-07-03 15:46:34OOP(継承、多態)とstaticは相互排他じゃないという説明がしたいのだけど、相変わらず「理系前提」脳が働いてしまっており、「整数はユークリッド聖域」=インターフェイス、「ユークリッド聖域には互除法が使える」=こういうのはstaticでOKとかいう例しか思い浮かばない。
2011-07-03 16:34:19@ufcpp C# の拡張メソッドと対比するのに適切な機能は、 Scala だと implicit conversion、 Rubyならオープンクラスな気がします。 #scalajp
2011-07-03 17:29:25単に「戻り値同型の原則 」だけを実現するならCanBuildFromなんて要らなくて、実装メソッドの戻り値型を自分自身の型で宣言すればいい。Javaでも5以降それで実現できる。でもそうするとmap等の実装を各クラスに書く必要がでてきてDRY原則に反する。(続く) #scala
2011-07-03 18:10:49