title: Scalaz instancing typeclass and case class
body: <p>This problem is pretty hard to explain. I try to implement a kind of <code>Arrow</code>, call it <code>MyArr</code>, which extends the <code>Arrow</code> trait from <code>scalaz</code>. However, <code>MyArr</code> is also a kind of Algbraic Data Type, so I make a few case classes out of if, and wrote down code like this(minimal example):</p>
  
  <pre><code>package org.timeless
  
  import scalaz._
  import Scalaz._
  import std.option._, std.list._
  
  sealed trait MyArr[A,B] extends Arrow[MyArr] {
    def id[A]: MyArr[A,A] = SId()
    def compose[A,B,C](s1: MyArr[B,C], s2: MyArr[A,B]): MyArr[A,C] =
      SRight(s2, s1)
    def arr[A,B](f: A=&gt;B): MyArr[A,B] = SPure(f)
    def first[A,B,C](s: MyArr[A,B]): MyArr[(A,C),(B,C)] = SPar(s, SId())
  }
  
  case class SId[A] () extends MyArr[A,A]()
  case class SRight[M[_],A,B,C](s1: MyArr[A,B], s2: MyArr[B,C]) extends MyArr[A,C]
  case class SPure[A,B](f: A=&gt;B) extends MyArr[A,B]
  case class SPar[M[_],A,B,C,D](s1: MyArr[A,B], s2: MyArr[C,D]) extends MyArr[(A,C),(B,D)]
  
  object MyArr {
    val b = SId[Int]()
    val c = SId[Int]()
    // val a: MyArr[Int,Int] = id[Int] // Error
    // val d = c compose b // Error
    // val d = b &gt;&gt;&gt; c // Error
    val d = b &gt;&gt;&gt; (b,c) // ??? Arguments
  }
  </code></pre>
  
  <p>As easily seen, the <code>id</code> function is actually the constructor of <code>SId</code>, etc. The classes themselves compile fine, but I don't see any way to actually use it as an <code>Arrow</code>. I actually came from Haskell programming, so I might be doing it totally wrong, but equivalent code in Haskell should be like this(with GADTs):</p>
  
  <pre><code>data MyArr a b where
    SId :: MyArr a b
    SRight :: MyArr a b -&gt; MyArr b c -&gt; MyArr a c
    SPure :: (a -&gt; b) -&gt; MyArr a b
    SPar :: MyArr a b -&gt; MyArr c d -&gt; MyArr (a,c) (b,d)
  
  instance Category MyArr where
    id = SId
    (.) = SRight
  
  instance Arrow MyArr where
    arr = SPure
    first s = SPar s SId
  </code></pre>