2010-04-30 3 views
5

J'essaie de savoir pourquoi l'appel in scalaz.ListW.<^> fonctionneparamètre Implicite dans Scalaz

def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match { 
    case Nil => ∅ 
    case h :: t => f(Scalaz.nel(h, t)) 
} 

Ma théorie minimale est:

trait X[T]{ 
    def y : T 
} 

object X{ 
    implicit object IntX extends X[Int]{ 
    def y = 42 
    } 
    implicit object StringX extends X[String]{ 
    def y = "y" 
    } 
} 
trait Xs{ 
    def ys[T](implicit x : X[T]) = x.y 
} 

class A extends Xs{ 
    def z[B](implicit x : X[B]) : B = ys //the call ∅ 
} 

qui produit:

import X._ 

scala> new A().z[Int] 
res0: Int = 42 

scala> new A().z[String] 
res1: String = y 

Est-ce valable? Puis-je obtenir le même résultat avec moins d'étapes?

Répondre

1

C'est tout ce qu'il y a à faire. Vous pouvez supprimer Xs et de conserver l'essence de l'exemple:

object A{ 
    def ys[T](implicit x : X[T]) = x.y 
} 
A.ys 

L'autre aspect intéressant de l'utilisation dans Scalaz est que l'argument de type à est déduit du type attendu B de l'expression.

J'ai récemment dû changer Zero pour être invariant dans son paramètre de type. Cela casse en fait l'inférence de ce type d'argument dans certains cas; vous pouvez le voir dans ce example. Il y a quelques billets ouverts liés qui seront heureusement être résolus par les changements sur ce branch.