Я пытаюсь написать общий метод, который обертывает все, что имеет scalaz.IsEmpty
в экземпляр класса типов Option
. Он должен возвращать None
для пустых значений и заключать их в Some
, если они не пусты. Вот что я придумал до сих пор:
import scalaz._
import Scalaz._
def asOption0[C](c: C)(implicit ev: IsEmpty[({ type B[A] = C })#B]) =
if (ev.isEmpty(c)) None else Some(c)
def asOption1[A, C[_]](c: C[A])(implicit ev: IsEmpty[C]) =
if (ev.isEmpty(c)) None else Some(c)
asOption0
работает для примитивных типов, таких как String
(с помощью >введите lambda, чтобы указать, что C
имеет форму B[_]
), а asOption1
работает для типов с конструктором унарного типа, например List
:
scala> asOption0("")
res1: Option[String] = None
scala> asOption1(List(1,2,3))
res0: Option[List[Int]] = Some(List(1, 2, 3))
scala> asOption0(List(1,2,3))
<console>:17: error: could not find implicit value for parameter
ev: scalaz.IsEmpty[[A]List[Int]]
scala> asOption1("hello")
<console>:17: error: could not find implicit value for parameter
ev: scalaz.IsEmpty[Comparable]
Можно ли написать один метод, который работает для String
, List
и типов более высокого типа одновременно?
*
и* -> *
. Это другое явное неявное преобразование кажется необходимым, например.Map
не удовлетворяет. У меня есть ощущение, что просто предоставления соответствующего экземпляра класса типов должно быть достаточно, чтобы использоватьasOption
. Извините за предыдущий вводящий в заблуждение заголовок! - person Frank S. Thomas   schedule 20.02.2013scalaz.Unapply
. Это решение не требует дополнительных неявных преобразований, а требует только экземпляраIsEmpty
. - person Frank S. Thomas   schedule 20.02.2013