为什么Scala不能推断出正确的ValidationNel类型?
在上面的代码中,isEven的返回类型被推断为scalaz.Validation[scalaz.NonEmptyList[\up>scalaz.NonEmptyList[String]是scalaz的子类型。NonEmptyList[\up>scalaz.NonEmptyList[String]是scalaz的子类型。NonEmptyList[\up>I将尝试解释有关以下内容的更多详细信息:为什么Scala不能推断出正确的ValidationNel类型?,scala,type-inference,scalaz,Scala,Type Inference,Scalaz,在上面的代码中,isEven的返回类型被推断为scalaz.Validation[scalaz.NonEmptyList[\up>scalaz.NonEmptyList[String]是scalaz的子类型。NonEmptyList[\up>scalaz.NonEmptyList[String]是scalaz的子类型。NonEmptyList[\up>I将尝试解释有关以下内容的更多详细信息: 为什么使用scalaz.Validation[scalaz.NonEmptyList[\up>我将尝试解
为什么使用scalaz.Validation[scalaz.NonEmptyList[\up>我将尝试解释以下方面的更多细节:
为什么scalaz.Validation[scalaz.NonEmptyList[uu]好的。我已经编辑了我的问题来添加一个表达式。你能回答为什么它在使用isEven的第一个变量时不编译吗?好的,如果我做对了,为M[t]定义的隐式将不适用于M[+t]或M[A,如果你要求隐式应用程序[t]Applicative是不变的,编译器会像您预期的那样查找Applicative[T]。好的,这很有意义。我已经编辑了我的问题以添加一个表达式。您能回答为什么在使用isEven的第一个变量时它不编译吗?好的,如果我理解正确,为M[T]定义的隐式将不适用于M[+T]或M[A如果您要求一个隐式应用程序[T],则编译器将按照您的预期查找一个应用程序[T]。
def isEven(x: Int) =
if (x % 2 == 0) x.successNel else "not even".failureNel
def isEven(x: Int): ValidationNel[String, Int] =
if (x % 2 == 0) x.successNel else "not even".failureNel
(isEven(4) |@| isEven(6) |@| isEven(8) |@| isEven(10)) {_ + _ + _ + _}
val some = Some(1)
val none = None
(some |@| none)(_ + _) // Cannot find implicit Applicative[Some] :(
implicit def ToApplyOpsUnapply[FA](v: FA)(implicit F0: Unapply[Apply, FA]) =
new ApplyOps[F0.M,F0.A](F0(v))(F0.TC)
implicit def unapplyMFA[TC[_[_]], M0[_[_], _], F0[_], A0](implicit TC0: TC[M0[F0, ?]]): Unapply[TC, M0[F0, A0]] {
type M[X] = M0[F0, X]
type A = A0
} =
new Unapply[TC, M0[F0, A0]] {
type M[X] = M0[F0, X]
type A = A0
def TC = TC0
def leibniz = refl
}
implicit def ValidationApplicative[L: Semigroup]: Applicative[Validation[L, ?]] =
new Applicative[Validation[L, ?]] {
override def map[A, B](fa: Validation[L, A])(f: A => B) =
fa map f
def point[A](a: => A) =
Success(a)
def ap[A, B](fa: => Validation[L, A])(f: => Validation[L, A => B]) =
fa ap f
}
trait Semigroup[F] { self => //F is invariant, unlike Option[+A]
def isEven(x: Int): Validation[NonEmptyList[_ <: String], Int] =
if (x % 2 == 0) x.successNel else "not even".failureNel
val res: String = foo(isEven(4))
def foo[FA](v: FA)(implicit F0: Unapply[Apply, FA]): String = "foo bar"
implicit def ValidationApplicative[L]: Applicative[Validation[L, ?]] =
new Applicative[Validation[L, ?]] {
override def map[A, B](fa: Validation[L, A])(f: A => B) =
fa map f
def point[A](a: => A) =
Success(a)
def ap[A, B](fa: => Validation[L, A])(f: => Validation[L, A => B]) =
//fa ap f
null
}