gpt4 book ai didi

scala - 如何为泛型类型编写 scalaz.IsEmpty 参数

转载 作者:行者123 更新时间:2023-12-01 10:56:31 26 4
gpt4 key购买 nike

我正在尝试编写一个通用方法来包装任何具有 scalaz.IsEmpty 的东西typeclass 实例到 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(通过使用 type 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]

是否可以编写一种同时适用于StringList 和更高类型的方法?

最佳答案

scala> asOption0(List(1,2,3))
<console>:17: error: could not find implicit value for parameter
ev: scalaz.IsEmpty[[A]List[Int]]

此错误告诉您它找不到列表的 IsEmpty 实例,这是因为类型参数无关紧要。 Scalaz 对任何列表都有一个隐式,无论类型参数如何。

该方法请求一个 IsEmpty[List[Int]],而 Scalaz 只有一个可用于 IsEmpty[List[_]]。由于 IsEmpty 不关心列表的内容,我们只是通过提供更详细的 IsEmpty 版本来使 asOption0 方法满意:

def asOption0[C](c: C)(implicit ev: IsEmpty[({ type B[_] = C })#B]) =
if (ev.isEmpty(c)) None else Some(c)

implicit def detailedIsEmpty[A, C[_]](implicit ev: IsEmpty[C]) =
ev.asInstanceOf[IsEmpty[({ type B[_] = C[A] })#B]]


asOption0("test") //> res0: Option[String] = Some(test)
asOption0(List(1, 2, 3)) //> res1: Option[List[Int]] = Some(List(1, 2, 3))
asOption0("") //> res2: Option[String] = None
asOption0(List[Int]()) //> res3: Option[List[Int]] = None

编辑

我重新审视了这个问题,找到了一个看起来更简洁的解决方案。我担心这不是 OP 想要的结果。

trait IsEmptyLike[F] {
def isEmpty(fa: F): Boolean
}

object IsEmptyLike {

implicit def case0[A](implicit ev: IsEmpty[({ type B[_] = A })#B]) =
new IsEmptyLike[A] {
def isEmpty(fa: A): Boolean = ev.isEmpty(fa)
}
implicit def case1[A[_], B](implicit ev: IsEmpty[A]) =
new IsEmptyLike[A[B]] {
def isEmpty(fa: A[B]): Boolean = ev.isEmpty(fa)
}
implicit def case2[A[_, _], B, C](implicit ev: IsEmpty[({ type D[X] = A[B, X] })#D]) =
new IsEmptyLike[A[B, C]] {
def isEmpty(fa: A[B, C]): Boolean = ev.isEmpty(fa)
}
}

def asOption[C](c: C)(implicit ev: IsEmptyLike[C]) =
if (ev.isEmpty(c)) None else Some(c)

关于scala - 如何为泛型类型编写 scalaz.IsEmpty 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14924707/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com