2016-05-20 4 views
2

Допустим, я определяю некоторый тип в черта, которая должна реализовать некоторый тип класса (как функтора):почему implicits не вызывают в этом сценарии типа зависимых путей

import cats.Functor 
import cats.syntax.functor.toFunctorOps 

trait Library { 
    type T[+A] 
    implicit val isFunctor: Functor[T] 
} 

Теперь я хочу, чтобы использовать эту библиотеку , Следующие работает отлично:

trait LibraryUser { 

    val l: Library 
    import l._ 

    def use: T[Boolean] = { 
    val t: T[Int] = ??? 
    t.map(_ => true) 
    } 
} 

Но при его использовании в способе с параметром вместо этого, импорт неявное не работает (вне комментировал линия не компилируется), и вы должны написать неявное для самостоятельно:

object LibraryUser1 { 
    def use(l: Library): l.T[Boolean] = { 
    import l._ 

    val t: T[Int] = ??? 
    //t.map(_ => true) 
    toFunctorOps(t)(isFunctor).map(_ => true) 
    } 
} 

Почему это случай/что можно сделать против него.

ответ

1

Это ранее было зарегистрировано как ошибка, в частности SI-9625. Имплицирует значения, зависящие от пути и возвращающие более высокие типы, не могут быть разрешены. Вот упрощенный пример с использованием стандартной библиотеки:

trait TC[F[_]] 

trait Foo { 
    type T[A] 
    implicit val ta: TC[T] 
} 

object Bar { 
    def use(foo: Foo) = { 
     import foo._ 
     implicitly[TC[T]] // fails to resolve, but `implicitly[TC[T]](ta)` is fine 
    } 
} 

К сожалению, даже самое очевидное использование неявного не удается:

object Bar { 
    def use(foo: Foo) = { 
     implicit val ta: TC[foo.T] = null 
     implicitly[TC[foo.T]] // nope! 
    } 
}