Scalaにおける型クラスの定義方法に関する議論

7
がくぞ @gakuzzzz

正直 Scalaだったら implicit conversion で型クラスの嬉しさと同じ事実現できると思うのだけど。

2013-11-19 14:21:22
Kenji Yoshida @xuwei_k

@gakuzzzz traitかabstract classを定義しておかないと、ここのコメントに書いたようなことが http://t.co/sBSe5leHEi

2013-11-19 14:27:09
がくぞ @gakuzzzz

@xuwei_k これは単に抽象型メンバでやってるからの様な。ちょっと帰宅してからサンプル書いてみますね。

2013-11-19 17:14:11
がくぞ @gakuzzzz

あー implicit conversion と 型クラスの一番の大きな違いは、いま扱おうとしている型のオブジェクトが存在してないと使えないのが implicit conversionでオブジェクトが無くても使えるのが型クラスだ。

2013-11-19 19:50:37
がくぞ @gakuzzzz

だから ApplicativeFunctor の pure みたいなのは型クラスじゃないと実現できないですね。

2013-11-19 19:51:44
がくぞ @gakuzzzz

逆にいえばそうじゃないものは implicit conversion でもいい気がする。

2013-11-19 19:52:35
ウィザード級エクセラー @BlackPrincessW

implicit conversionと型クラスはそもそも概念レベルで違う物では?

2013-11-19 19:55:13
がくぞ @gakuzzzz

@BlackPrincessW 概念は全然違うものだけど、解決しようとしている問題は同じような気がしています

2013-11-19 20:00:27
がくぞ @gakuzzzz

@lyrical_logical @BlackPrincessW あー implicit conversion は型変換の型クラスインスタンス定義だっていうのはシンプルで判りやすいですね。

2013-11-19 21:24:35
がくぞ @gakuzzzz

@xuwei_k https://t.co/0U7VHAlmZk こんな感じの定義なら前述の様なList側を固定したいケースも対応できるし、A型クラスのインスタンスがあればB型クラスのインスタンスが定義できる=A型の暗黙変換ができればB型へも暗黙変換できるみたいに表現可能かと

2013-11-20 02:35:57
がくぞ @gakuzzzz

@xuwei_k もちろん、implicit conversionの場合、2段階以上の暗黙変換はやってくれないのでその辺は型クラスの方が便利だし、書くのもずっと型クラスの方が楽ですけどね;-)

2013-11-20 02:37:11
がくぞ @gakuzzzz

pureみたいなインスタンスが無い時に使いたい処理は型クラスじゃないと書けないし、なので型クラス使っとけって感じですね。

2013-11-20 02:39:36
Kenji Yoshida @xuwei_k

@gakuzzzz ん?なにも解決してないような。ここでの説明 http://t.co/sBSe5leHEi がわかりづらかったかもしれませんが、Listを固定すること自体が目的ではなく、「ある型クラスAを引数の制約として要求する関数を書くとき困る」というのが言いたかったことで

2013-11-20 06:50:39
がくぞ @gakuzzzz

@xuwei_k その制約の場合、ある型引数AがFunctor[B, A]に暗黙変換できるか、という制約になるので<%<があればいけると思いましたが<%<が既に無かったですねorzまぁ=:=も型クラスですし、implicit値が見つかるか否かで制限する場合は暗黙変換じゃ無理ですね

2013-11-20 07:39:57
がくぞ @gakuzzzz

あ、 <%< は <% でいいじゃんって話なのか。であれば def hoge[A <% Functor[_, A]] で制約が表現できる気がする。

2013-11-20 07:47:38
Kenji Yoshida @xuwei_k

@gakuzzzz <%<自体は糖衣構文なので、Function1のimplicitパラメータを要求するように明示的に書けばいいです。がそこが問題じゃないという話ですね。Traverseのsequenceよりこっち https://t.co/35t8z7RL2K のほうがいいかな

2013-11-20 07:53:10
がくぞ @gakuzzzz

@xuwei_k ん?単に def compose[G[_] <% Functor[_, G]](composee: G): Functor[A, ({type λ[α] = Repr[G[α]]})] みたいな感じになるだけではないですか?

2013-11-20 08:03:17
Kenji Yoshida @xuwei_k

@gakuzzzz その場合にcomposeして返ってきたFunctorの一番目の型引数のAが、その時点ですでに固定されていることが問題

2013-11-20 08:14:29
がくぞ @gakuzzzz

@xuwei_k それは型引数をもう一つ増やせばよいだけでは?

2013-11-20 08:17:43
がくぞ @gakuzzzz

なんかimplicit conversionの世界に型クラスをあてこもうとしておかしくなってる気配。

2013-11-20 08:21:00
Kenji Yoshida @xuwei_k

@gakuzzzz うーん、うまく説明できないのでコード書いてみます。あと、Functor[A, F[_]]のすべてのメソッドがF[A]を引数として使うとは限らないことがポイントですかね(Scalazだとliftとかcounzip) https://t.co/q1h89W2SVK

2013-11-20 08:22:33
がくぞ @gakuzzzz

@xuwei_k あーAの固定が問題というのが何となくわかった気がします。lift も pure と同じで、実際インスタンスを使わずに処理をする系なのでそういうのは型クラスじゃないと表現できない気がしますね。

2013-11-20 08:32:34
Kenji Yoshida @xuwei_k

@gakuzzzz あーいや、そもそもcompose呼び出す際の「composee: G」というのがおかしい?その時点で受け取るとしたらcomposee: Repr[G[A]] だろうし、もしそれ受けとっても、composeの実装が書けないような

2013-11-20 08:34:25