2010-04-30 33 views
5

Trato de averiguar por qué la llamada in scalaz.ListW.<^> funcionaparámetro implícito en Scalaz

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

Mi teoría mínima es:

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 ∅ 
} 

que produce:

import X._ 

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

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

¿Es esta válida? ¿Puedo lograr el mismo resultado con menos pasos?

Respuesta

1

Eso es todo. Podría quitar Xs y conservar la esencia del ejemplo:

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

El otro aspecto interesante del uso de Scalaz es que el tipo de argumento a se infiere del tipo esperado B de la expresión.

Tuve que cambiar Zero para ser invariante en su parámetro de tipo. En realidad, esto rompe la incompatibilidad de este tipo de argumento en algunos casos; Puedes ver esto en este example. Hay algunos tickets abiertos relacionados que con suerte serán resueltos por los cambios en este branch.