Scala Kittens: неявное значение Sequencer, похоже, не работает с синтаксисом, привязанным к контексту - PullRequest
0 голосов
/ 30 октября 2019

В моем понимании следующие две функции и их вызовы должны быть идентичны:

def f1[L1 <: HList, L2](xs: L1)(implicit sequencer: Sequencer.Aux[L1, Option, L2]) {
  println(xs.sequence)
}

def f2[L1 <: HList : Sequencer.Aux[*, Option, L2], L2](xs: L1) {
  println(xs.sequence)
}

f1[Option[Int] :: Option[String] :: HNil, Int :: String :: HNil](Some(42) :: Some("foo") :: HNil)
f2[Option[Int] :: Option[String] :: HNil, Int :: String :: HNil](Some(42) :: Some("foo") :: HNil)

Однако вызов f2 не компилируется:

could not find implicit value for evidence parameter of type cats.sequence.Sequencer[Option[Int] :: Option[String] :: shapeless.HNil]{type F[X] = Option[X]; type LOut = Int :: String :: shapeless.HNil}

Компиляция Scala кажетсяразвернуть псевдоним типа Sequencer.Aux во втором случае и не может создать подходящий неявный.

Если я непосредственно определяю свою функцию с расширенным типом, то не может быть создан и неявный:

def f3[L1 <: HList, L2](xs: L1)(implicit sequencer: Sequencer[L1]{type F[X] = Option[X]; type LOut = L2}) {
  println(xs.sequence)
}

Помимо неудобства невозможности использовать более компактный контекстно-связанный синтаксис, есть две вещи, которые я не понимаю в этой ситуации:

  1. почему типнеявные доказательства расширяются, только если я использую синтаксис, связанный с контекстом? (и есть ли более семантические различия между двумя синтаксисами?)
  2. Почему Scala не может создать подходящее неявное для расширенного случая? В конце концов, Sequencer.Aux - это только псевдоним типа, определенный следующим образом:
type Aux[L <: HList, F0[_], LOut0] = Sequencer[L] {
  type F[X] = F0[X]
  type LOut = LOut0
}

Я бы ожидал, что оба типа будут вести себя одинаково.

1 Ответ

0 голосов
/ 30 октября 2019

Похоже, ошибка. Об ошибках следует сообщать здесь: https://github.com/scala/bug/issues

Я попытался создать минимальный пример.

И, возможно, я упростил пример, но теперь у меня есть проблемы даже с HNil case.

Для

import cats.Applicative
import shapeless.{::, HList, HNil}
import cats.instances.option._

trait Sequencer[L <: HList] extends Serializable {
  type F[_]
}

object Sequencer {
  type Aux[L <: HList, F0[_]] = Sequencer[L] {
    type F[X] = F0[X]
  }

  implicit def nil[F0[_]](
    implicit F: Applicative[F0]
  ): Aux[HNil, F0] = null
}

implicitly[Sequencer.Aux[HNil, Option]] компилируется, но implicitly[Sequencer[HNil]{type F[X] = Option[X]}] не делаетt и есть предупреждение (scalacOptions += "-Xlog-implicits")

//Information: App.this.Sequencer.nil is not a valid implicit value for App.Sequencer[shapeless.HNil]{type F[X] = Option[X]} because:
//hasMatchingSymbol reported error: could not find implicit value for parameter F: cats.Applicative[Option[X]]

И, вероятно, здесь мы можем увидеть причину: could not find implicit value for parameter F: cats.Applicative[Option[X]] должно быть could not find implicit value for parameter F: cats.Applicative[Option].

Но по какой-то причине, если я удалюimplicit F: Applicative[F0] затем для

import shapeless.{::, HList, HNil}

trait Sequencer[L <: HList] extends Serializable {
  type F[_]
}

object Sequencer {
  type Aux[L <: HList, F0[_]] = Sequencer[L] {
    type F[X] = F0[X]
  }

  implicit def nil[F0[_]](): Aux[HNil, F0] = null
}

implicitly[Sequencer.Aux[HNil, Option]] не компилируется, хотя implicitly[Sequencer.Aux[HNil, Option]](Sequencer.nil()) компилируется.

implicitly[Sequencer[HNil]{type F[X] = Option[X]}] тоже не компилируется. И если мы напишем implicitly[Sequencer[HNil]{type F[X] = Option[X]}](Sequencer.nil()), мы увидим, почему

//Error: inferred kinds of the type arguments (Option[X]) do not conform to the expected kinds of the type parameters (type F0).
//Option[X]'s type parameters do not match type F0's expected parameters:
//class Option has one type parameter, but type F0 has one

... has one type parameter, but ... has one показывает, что это ошибка.

Отслеживание ошибок показывает открытые проблемы для "неявных" и "высшихвид "

https://github.com/scala/bug/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+implicit+higher-kind

...