これは私が問題を定義するための2番目の試みです。スカラーズの類義語と継承
代数型を定義し、その上に単純な型定義を定義できるようにしたいとします。Show
としましょう。 Haskellで私は:私はEmptyTree
を入力すると今
data Tree a = EmptyTree | Node a deriving (Show)
、 - それはShow
に属しているので、Haskellは、それを表示することができます。
今、私はScalaで同じことをしようとしています:
sealed abstract class Tree[+T]
case object EmptyTree extends Tree[Nothing]
case class Node[T](value: T) extends Tree[T]
その後、私はそれを回避Show
を定義します。
implicit def show[T] = Show.showA[Tree[T]]
私はprintln((EmptyTree : Tree[Int]).show)
を行うことができます。しかし、私はprintln(EmptyTree.show)
(応答がvalue show is not a member of object EmptyTree
ある)
を行うことができない私は、追加の書き込みをする必要があります:
implicit class MyShowOps[A, +T <: Tree[A]](t: T) {
def showMy(implicit ev: Show[Tree[A]]): String = ev.shows(t)
}
をそしてだけにして、私はprintln(EmptyTree.showMy)
を行うことができますそれはまだ私は信じて、正しい音ではありません。私は間違ったことをやろうとしていますが、Show
のようなものを使用しないでください。Tree[T]
として自分の工事を使うか、Scalazから適切な工事が行えません。
私はscalazのソースで 'val emptyTree:Tree [Nothing] ..'のようなパターンを見たことがありますが、そのようにした理由を理解できませんでした。今私には明らかです。私が理解していないものがまだあります。私が行ったようにscalaz 'ShowOps'が定義されていなかった特別な理由はありますか? 'emptyTree'や' node [T] 'のようなラッパーメソッドを定義しなければならないよりも簡単です – Archeg
アップストリームのコンストラクターパターンは、これらの問題の多くを1か所で解決しますが、サブタイプのインスタンスを提供すると、コードの一般的に、Scalazはサブタイプに対応するために抜け出すことはありません(ほとんどのタイプクラスは不変で、インスタンスはサブタイプには提供されません)。 –