型クラスのインスタンスはグローバルで1つであるべきか

9
kmizu @kmizu

@gakuzzzz Kotlinは複雑じゃないScalaを目指して作られたはずなので、複雑さをかなり増す(それに見合った表現力は得られると思うわけですが)型クラスは嫌ったんじゃないですかね。Scalaのimplicitより良い形で型クラス実現してくれればよかったと思いますが

2015-09-24 18:38:13
がくぞ @gakuzzzz

型クラスは基本的に一つの型に対して一個しか定義できないので、Monoid とか Applicative とか一つの型に複数の定義が可能なものに対して、無理やり別の型を定義して現実回してるのは違和感があって、この辺もっとすっきり解決する方法は無いものか……と思っている

2015-09-24 18:46:10
kmizu @kmizu

@gakuzzzz 型クラスのインスタンスがglobalなせいで一つの型につき一つしか定義できないのは(かつての)Haskellの制約であって、そこは後発であるScalaが(localにimportすることで型クラスインスタンスを導入する)クリアした部分では?と思うわけですが…。

2015-09-24 18:49:22
がくぞ @gakuzzzz

@kmizu 確かに。 Scalaz脳でした……。

2015-09-24 18:50:27
kmizu @kmizu

Scalaのimplicitsに関して思うことは、やはり型クラスのインスタンス(implicitな値)の探索スコープが広すぎるというところにつきる。この辺のルールをもう少し厳しくすればコンパイル速度に寄与できんかな…evernote.com/shard/s29/sh/2…

2015-09-24 18:57:37
kmizu @kmizu

型クラスと型コンストラクタ多相は抱き合わせ販売しないと魅力が半減するのであって、どちらか片方だけだと少し厳しいものがある。

2015-09-24 19:02:51
がくぞ @gakuzzzz

Scalaz が何故このアプローチを取らなかったんだろう? twitter.com/kmizu/status/6… ライブラリ利用側に負担がでかくなるからかな?

2015-09-24 19:12:38
かず(原材料に小麦粉を含む) @kazzna

@gakuzzzz @kmizu 今からでも個別インポートしたら一個ずつインポートできるように互換性を保ったまま調整できないものでしょか?Scalaz._に一個一個入れるのはさすがに大変な量ですかね?

2015-09-24 19:21:15
kmizu @kmizu

@gakuzzzz そこらへんの解説はコミッタの方に期待することとして(ぇ、型クラスのインスタンスを個別にimportするのだと面倒くさいのを嫌ったのかなと個人的には思っています。

2015-09-24 19:21:51
Kenji Yoshida @xuwei_k

.@gakuzzzz @kmizu そのあたりに関してekmettせんせーが具体的にScalaコードも出して言及してる動画(15:00〜20:00 くらい)があるので参考までに youtu.be/hIZxTQP1ifo?t=… pic.twitter.com/IMcCdOwWhL

2015-09-24 19:43:48
拡大
がくぞ @gakuzzzz

@xuwei_k @kmizu おお、あざます。帰宅したら見てみます!

2015-09-24 19:47:01
ると @cocoa_ruto

@kmizu その辺の議論ちゃんと追ってないんだけど、coherenceなんて要らなかったんだという結論になったの?

2015-09-24 19:51:41
kmizu @kmizu

@cocoa_ruto というと?Scalaのimplicit(による型クラスの実現)だとcoherenceが失われるという話?

2015-09-24 19:53:09
kmizu @kmizu

@cocoa_ruto Monoid[T]のインスタンスとして、SumMonoid extends Monoid[Int]とMultMonoid extends Monoid[Int]が同時に存在してるとなにかいけないことが発生する?とかそういう話?

2015-09-24 19:58:20
ると @cocoa_ruto

@kmizu 例えば探索木による不変な集合を実装したSetがあったとして、Set Foo同士を連結しようとしたときに、そのふたつが同じインスタンス宣言に基づくものであるか保証できないと、効率よく連結できない。効率悪いならともかく、一般にはプログラムの動作を保証できなくなる。

2015-09-24 19:59:02
がくぞ @gakuzzzz

明示的に渡せる事によって、証明としての力が弱くなってしまうとかかな?

2015-09-24 20:00:44
kmizu @kmizu

@cocoa_ruto 保証はされるのでは?def add[T](a: Set[T], b: Set[T])(implicit sets: Sets[T]): Set[T] = ???(setsを使う) で、setsのインスタンスは同じ呼び出し元の元でuniqueだよね。

2015-09-24 20:07:30
ると @cocoa_ruto

@kmizu aは例えば整数を昇順に格納していて、bは降順に格納している場合、その連結を計算するときに部分木の共有ができない。

2015-09-24 20:09:12
kmizu @kmizu

@cocoa_ruto 確かに、自分の提示した例だとそういうケースで部分木の共有ができなくなるとは思うけど、部分木の共有ができるときは効率が良ければ十分なのでは?(共有できるようにするには提示した定義を書き換える必要はあるが)

2015-09-24 20:13:13
kmizu @kmizu

@cocoa_ruto 型クラスの(変な)インスタンスを選んでしまうと効率が悪くなるけど、別のインスタンスを選べば十分に効率が良いように定義すればそれでいいのでは?というのが自分の考え。

2015-09-24 20:14:44
ると @cocoa_ruto

@kmizu 共有できるというのをどうやって判定するの? 実行時でも簡単ではないのでは?

2015-09-24 20:16:05
kmizu @kmizu

@cocoa_ruto ドキュメントに書く。

2015-09-24 20:16:36
ると @cocoa_ruto

@kmizu coherenceを自分で保ってください、保たなかったら動作は未定義です以上のことは書けないのでは?

2015-09-24 20:20:20
kmizu @kmizu

@cocoa_ruto 保たれるべきcoherenceは個々の型クラスごとに、作成者はわかってるはずなのでそれを書けばよくて、保たなかった場合の動作は言うように未定義動作でいいと思っている。

2015-09-24 20:24:17