Котята - неоднозначный импорт (опять же)

Этот ответ https://stackoverflow.com/a/56366311/2682459 показывает, как можно использовать объект для предоставления пользовательской реализации класса типов при использовании Kitten. Применение того же принципа к следующему коду не работает:

package com.xxx.yyy.zzz

import cats._, cats.derived._, cats.implicits._

object Test extends App {

  case class Inner(double: Double)

  case class Outer(inner: Inner, s: String)

  implicit object doubleEq extends Eq[Double] {
    override def eqv(x: Double, y: Double): Boolean = Math.abs(x - y) < 0.1
  }

  implicit val outerEq: Eq[Outer] = {
    import derived.auto.eq._
    derived.semi.eq[Outer]
  }

  implicitly[Eq[Double]]

  val testCC1 = Outer(Inner(1.01d), "BlahBlahBlah")
  val testCC2 = Outer(Inner(1.00d), "BlahBlahBlah")

  println(testCC1 === testCC2)

}

implicitly[Eq[Double]] показывает, что у меня снова неоднозначные имплициты:

Error:(20, 13) ambiguous implicit values:
 both value catsKernelStdOrderForDouble in trait DoubleInstances of type => cats.kernel.Order[Double] with cats.kernel.Hash[Double]
 and object doubleEq in object Test of type com.xxx.yyy.zzz.Test.doubleEq.type
 match expected type cats.Eq[Double]
  implicitly[Eq[Double]]

Как мне обойти это? Я действительно не хочу выбирать неявные атрибуты кошек, которые я импортирую, поскольку это не очень масштабируемо!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Измените свой импорт. Не импортировать cats.instances.double._

import cats._, cats.derived._
import cats.instances.string._ // Outer uses Double and String
import cats.syntax.eq._ // for ===

Обе

implicit val doubleEq: Eq[Double] = new Eq[Double] {
  override def eqv(x: Double, y: Double): Boolean = Math.abs(x - y) < 0.1
}

а также

implicit object doubleEq extends Eq[Double] {
  override def eqv(x: Double, y: Double): Boolean = Math.abs(x - y) < 0.1
}

работай.

http://eed3si9n.com/herding-cats/import-guide.html

https://blog.softwaremill.com/9-tips-about-using-cats-in-scala-you-might-want-to-know-e1bafd365f88 совет 2)

Хороший! Я надеялся, что будет способ не так жестко контролировать импорт кошек. Стремясь создать что-то, что надежно работает независимо от того, переопределяю ли я двойники или другой тип/типы, без необходимости изменять импорт. Поскольку существует иерархия имплицитов, это возможно?

user2682459 30.05.2019 09:25

Что ж, вы можете импортировать cats.syntax.all._ вместо cats.syntax.eq._, поскольку неоднозначность заключается в экземплярах, а не в синтаксисе.

Dmytro Mitin 30.05.2019 09:52

Дело в том, что я не хочу импортироватьcats.instances.long,cats.instances.xxx всякий раз, когда изменяется класс моего случая, так как мне нужно решение, которое работает для любого класса случая.

user2682459 30.05.2019 10:59

Еще немного игры - кажется, это дает мне то, что я хочу:

import cats._
import cats.derived._
import cats.syntax.eq._
import derived.auto.eq._

object CustomImplicits extends cats.instances.AllInstances {
  implicit object doubleEq extends Eq[Double] {
    def eqv(x: Double, y: Double): Boolean = Math.abs(x - y) < 0.1
  }
}

object Test extends App {

  case class Inner(double: Double)

  case class Outer(inner: Inner, s: String)

  import CustomImplicits._

  implicitly[Eq[Double]]

  val testCC1 = Outer(Inner(1.01d), "BlahBlahBlah")
  val testCC2 = Outer(Inner(1.00d), "BlahBlahBlah")
  val testCC3= Outer(Inner(2.00d), "BlahBlahBlah")

  println(testCC1 === testCC2) //True
  println(testCC2 === testCC3) //False

}

Другие вопросы по теме