Строка сопутствующий объект в Scala
Учитывая тип, который имеет "конвертер", я хотел бы иметь автоматическое преобразование при вызове метода с использованием объекта-компаньона этого типа. То есть, учитывая следующее определение,
case class Converted(name: String)
trait Converter[A] {
def perform: Converted
}
implicit val StringConverter = new Converter[String] {
def perform = Converted("String")
}
заставить следующий код работать:
implicit def toConverter(a: String.type): Converted =
implicitly[Converter[String]].perform // Error: `Found String.type, required AnyRef`
def f(needsConverted: Converted) = ???
f(String) // <- That's what I would like to be able to write.
Но это терпит неудачу, и обе попытки преобразования терпят неудачу. Обратите внимание, что я не могу изменить f
потому что он предоставляется сторонней библиотекой и их много.
- Могу я сделать
f(String)
компилировать с использованием имплицитов?
Если это невозможно для строк, как насчет классов, у которых есть объект-компаньон, могу ли я сделать это в общем случае так:
object TheClass
case class TheClass()
implicit val TheClassConverter = new Converter[TheClass] {
def perform = Converted("TheClass")
}
implicit def toConverter[A: Converter](a: A.type): Converted =
implicitly[Converter[A]].perform // Error: `Not found value A`
implicit def toConverter(a: TheClass.type): Converted =
implicitly[Converter[TheClass]].perform // This works but is not generic
f(TheClass) // This works.
- Могу ли я сделать первый
toConverter
Скомпилировать?
3 ответа
Вместо определения неявного экземпляра для типа MyClass
Вы можете определить неявный экземпляр для типа компаньона MyClass.type
,
implicit val TheClassConverter: Converter[MyClass.type] = new Converted[MyClass.type] {
def perform = Converted("MyClass")
}
Можно ли сделать компиляцию f(String) с использованием имплицитов?
Нет. Вы можете определить значение под названием String
конечно, но это не будет связано с типом String
,
implicit toConverter[A: Converter](a: A.type): Converted = implicitly[Converter[A]].perform
A
в A.type
должно быть значением; это не связано с параметром типа A
,
На самом деле, что касается системы типов Scala, нет никакой связи между классом / признаком и его сопутствующим объектом. Таким образом, вы не можете делать то, что вы хотите в общем.
Конечно, если вы не настаиваете на использовании ()
вместо []
становится тривиально
def f1[A: Converter] = f(implicitly[Converter[A]].perform)
f1[String]
f1[TheClass]
Не уверен, что вы пытаетесь сделать, но следующие работы для меня
case class Converted(name: String)
trait Converter[A] {
def perform: Converted
}
implicit def toConverted(name: String) = Converted("String")
implicit def toIntConverted(int: Int) = Converted("Int")
def f(needsConverted: Converted): String = needsConverted.name
f("some")
f(5)