Что не так с кодировкой классов типов на основе делегирования - PullRequest
0 голосов
/ 26 мая 2018

Согласованность типов классов является общеизвестной проблемой.

Например, Monad должно быть Functor, а Traversable также должно быть Functor.Если has to be представлено через наследование (Monad[F[_]] extends Functor[F[_]]), то, скорее всего, будет неясность в неявном разрешении.

Я применил эмпирическое правило: если у вас есть проблема с наследованием, замените его делегированием.Вот пример:

  trait Semigroup[A] {
    def append(a: A, b: A): A
  }

  trait Monoid[A] {
    def zero(): A
    val semigroup: Semigroup[A]
    def append(a: A, b: A): A = semigroup.append(a, b)
  }

  implicit object IntSemigroup extends Semigroup[Int] {
    override def append(a: Int, b: Int): Int = a + b
  }

  implicit object IntMonoid extends Monoid[Int] {
    override def zero(): Int = 0
    override val semigroup: Semigroup[Int] = IntSemigroup
  }

  def main(args: Array[String]): Unit = {
    println(implicitly[Monoid[Int]].append(2, 3))
  }

Я полагаю, что этот подход не работает, поскольку он очевиден, но не используется в scalaz / cats.Не могли бы вы указать мне на проблемы?

1 Ответ

0 голосов
/ 26 мая 2018

Представляя его с помощью наследования, вы получаете логический вывод бесплатно - Monad автоматически становится Functor.Представляя его с помощью делегирования, вы этого не сделаете.

Вам придется определить множество неявных преобразований, чтобы обойти это, что было бы больно.Но (простые) неявные преобразования не объединяются автоматически в Scala, поэтому с ними они все равно не выведут Functor из Monad через промежуточный класс типов Applicative.

PS На практикевы обычно не получаете двусмысленности в разрешении, если все делаете правильно.Это означает, что (а) используйте foo.some вместо Some(foo) и тому подобное, и (б) используйте классы значений или подобные им для семантической неоднозначности типов, для которых вы хотите использовать разные экземпляры.И если ничего не помогает, явно передайте экземпляр (что нельзя сделать в Haskell).

...