2013-04-27 7 views
6

solito Scalaz di Unapply fa un buon lavoro, ma sembra per abbattere qui con traverseU:Scalaz's Unapply: perché non attraversareU lavorare con lo Stato? Perché esistono attraversamenti?

scala> import scalaz._, Scalaz._, Unapply._ 
import scalaz._ 
import Scalaz._ 
import Unapply._ 

scala> val stateMonadInstance = unapplyMAB2[Monad, State, Int, Unit](IndexedStateT.stateMonad[Int]).TC 
stateMonadInstance: scalaz.Monad[[X]scalaz.IndexedStateT[[+X]X,Int,Int,X]] = [email protected] 

scala> List(1, 2, 3).traverseU((i: Int) => stateMonadInstance.pure(i)) 
<console>:18: error: Unable to unapply type `scalaz.IndexedStateT[[+X]X,Int,Int,Int]` into a type constructor of kind `M[_]` that is classified by the type class `scalaz.Applicative` 
1) Check that the type class is defined by compiling `implicitly[scalaz.Applicative[<type constructor>]]`. 
2) Review the implicits in object Unapply, which only cover common type 'shapes' 
(implicit not found: scalaz.Unapply[scalaz.Applicative, scalaz.IndexedStateT[[+X]X,Int,Int,Int]]) 
       List(1, 2, 3).traverseU((i: Int) => stateMonadInstance.pure(i)) 
            ^

Il metodo traverseS sembra essere stata creata come una soluzione per questo problema, qualunque esso sia:

scala> List(1, 2, 3).traverseS((i: Int) => stateMonadInstance.pure(i)) 
res11: scalaz.State[Int,List[Int]] = [email protected] 

Ma sto cercando di scrivere una libreria generica rispetto alla monade in questione, quindi non è una buona idea. Qualcuno sa qual è il problema esatto qui che impedisce a questo di funzionare, e se c'è una soluzione alternativa che non richiede un involucro speciale per State?

risposta

2

Ok, questo funziona:

scala> import scalaz._, Scalaz._, Unapply._ 
import scalaz._ 
import Scalaz._ 
import Unapply._ 

scala> val unapply = unapplyMAB2[Monad, State, Int, Unit](IndexedStateT.stateMonad[Int]) 
unapply: scalaz.Unapply[scalaz.Monad,scalaz.State[Int,Unit]]{type M[X] = scalaz.State[Int,X]; type A = Unit} = [email protected] 

scala> List(1, 2, 3).traverseU((i: Int) => unapply.TC.pure(i)) 
res0: scalaz.IndexedStateT[scalaz.Id.Id,Int,Int,List[Int]] = [email protected] 

infatti proprio regolari vecchi traverse opere in questo caso:

scala> List(1, 2, 3).traverse((i: Int) => unapply.TC.pure(i)) 
res1: unapply.M[List[Int]] = [email protected] 

Suppongo che quello che sta succedendo è che ho bisogno di avere l'istanza Unapply portata per sapere a quali tipi si riferisce il campo TC.

Problemi correlati