首页 > 解决方案 > 来自 scalawithcats 书:值 asRight 不是类型参数 A 的成员

问题描述

我正在阅读“与猫在一起的斯卡拉”一书。在第 339 页上,我复制了示例代码,但运行时出现“值 asRight 不是类型参数 A 的成员”错误。

我的代码如下,和书上的完全一样

import cats.Semigroup
import cats.instances.list._
import cats.syntax.either._
import cats.syntax.semigroup._

/**
 * This one is called implementation check and it is better
 *
 * @tparam E An template Error Type
 * @tparam A Template Data Type
 */
sealed trait Check[E, A] {
  import Check._

  def and(that: Check[E, A]): Check[E, A] =
    And(this, that)

  def apply(a: A)(implicit s: Semigroup[E]): Either[E, A] =
    this match {
      case Pure(f)          => f(a)
      case And(left, right) =>
        (left(a), right(a)) match {
          case (Right(a), Right(_)) => a.asRight
          case (Right(_), Left(e))  => e.asLeft
          case (Left(e), Right(_))  => e.asLeft
          case (Left(e1), Left(e2)) => (e1 |+| e2).asLeft
        }
    }
}

object Check {
  final case class And[E, A](left: Check[E, A], right: Check[E, A]) extends Check[E, A]

  final case class Pure[E, A](func: A => Either[E, A]) extends Check[E, A]

  def pure[E, A](f: A => Either[E, A]): Check[E, A] = Pure(f)

}

val a: Check[List[String], Int] =
  Check.pure {
    v =>
      if (v > 2) v.asRight
      else List ("Must be > 2").asLeft
  }

val b: Check[List[String], Int] =
  Check.pure {
    v =>
      if (v < - 2) v.asRight
      else List ("Must be < -2").asLeft
  }

val check: Check[List[String], Int] = a and b
check(5)
check(-10)

我将上面的代码放在脚本文件'check.sc'中,我的猫依赖是:

libraryDependencies += "org.typelevel" %% "cats-core" % "2.1.0"

当我使用 IDEA 运行代码片段时,它返回给我

value asRight is not a member of type parameter A
case (Right(a), Right(_)) => a.asRight

这是IDEA错误还是什么?因为如果我将代码粘贴到 scala 文件中并使用 main 函数运行,它就不再抱怨了。

下面是正确的:

package org.scala.ch10

import cats.Semigroup
import cats.instances.list._
import cats.syntax.either._
import cats.syntax.semigroup._

/**
 * This one is called implementation check and it is better
 *
 * @tparam E An template Error Type
 * @tparam A Template Data Type
 */
sealed trait CheckADT[E, A] {
  import CheckADT._

  def and(that: CheckADT[E, A]): CheckADT[E, A] =
    And(this, that)

  def apply(a: A)(implicit s: Semigroup[E]): Either[E, A] =
    this match {
      case Pure(f)          => f(a)
      case And(left, right) =>
        (left(a), right(a)) match {
          case (Right(a), Right(_)) => a.asRight
          case (Right(_), Left(e))  => e.asLeft
          case (Left(e), Right(_))  => e.asLeft
          case (Left(e1), Left(e2)) => (e1 |+| e2).asLeft
        }
    }
}

object CheckADT {
  final case class And[E, A](left: CheckADT[E, A], right: CheckADT[E, A]) extends CheckADT[E, A]

  final case class Pure[E, A](func: A => Either[E, A]) extends CheckADT[E, A]

  def pure[E, A](f: A => Either[E, A]): CheckADT[E, A] = Pure(f)

}

object Main {
  def main(args: Array[String]): Unit = {
    val a: CheckADT[List[String], Int] =
      CheckADT.pure {
        v =>
          if (v > 2) v.asRight
          else List ("Must be > 2").asLeft
      }

    val b: CheckADT[List[String], Int] =
      CheckADT.pure {
        v =>
          if (v < - 2) v.asRight
          else List ("Must be < -2").asLeft
      }

    val check: CheckADT[List[String], Int] = a and b
    println(check(5))
    println(check(-10))
  }
}

那么我的“sc”文件有什么问题?

标签: scalafunctional-programmingscala-catscats-effect

解决方案


推荐阅读