顾名思意,Either表示或者是这一个元素或者是那个元素。这样在异常处理的时候就非常有用了。 我们先看一下Either的定义: sealed abstract class Either[+A, +B] extends Product with Serializable 它有两个子类Left和Right 我们看下怎么用Either的常规使用: def positive(i: Int): Either[String,Int] = if (i > 0) Right(i) else Left(s"nonpositive Either怎么在代码中消除程序错误,将错误封装在Either中。 我们看下怎么用Either来将其封装起来: scala> def addInts2(s1: String, s2: String): Either[NumberFormatException,Int]=
在以下的函数中我们可以用一个函数 (A,B) => C 把两个Either[A],Either[B]组合成Either[C]: 1 //用递归算法 2 def map2[EE ,我必须想办法把Either管子里的那个元素取出来计算完后塞到一个新的Either管子里去。 以上我们已经实现了map,flatMap我们可以使用for comprehension来实现: aa <- a: Either - 从Either管子取出元素 yield 产生新的Either。 ("Tiger",18) //> res2: ch4.either.Either[String,ch4.either.Person] = Right /> res4: ch4.either.Either[String,ch4.either.Person] = Left(Invalid Name) mkPerson输入参数正确时返回Right。
scala标准库提供了一个Either类型,它可以说是Option的升级版。 与Option相同,Either也有两种状态:Left和Right,分别对应Option的None和Some,不同的是Left可以返回一个值。我们通常用这个值来表述异常信息。 scalaz也提供了自己版本的Either,并用\/来分辨表示,以及两种状态-\/和\/-。我想scalaz特别提供\/是有原因的:\/不单是一种类型,它是一种type class。 如此能够方便把Either功能整合到FP编程中去。 我们先看看\/的定义:scalaz/Either.scala sealed abstract class \/[+A, +B] extends Product with Serializable { .
scalaz还提供了个type class叫Validation。乍看起来跟\/没什么分别。实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数。通过
expression: $<AND:$<C_COMPILER_ID:GNU>;,$<CONFIG:Release>> Parameters to $<OR> must resolve to either 表达式在实现时每个子表达返回结果是作为一个字符串处理的,如果加了空格,返回的字符串后面就多了个空格,就是不是‘1’或‘0’,而是‘1 ’或‘0 ’,所以报错Parameters to $<OR> must resolve to either
Either remove Logback or the competing implementation SLF4J: Class path contains multiple SLF4J bindings Either remove Logback or the competing implementation (class org.slf4j.helpers.NOPLoggerFactory loaded
django/db/backends/sqlite3/base.py", line 39, in <module> raise ImproperlyConfigured("Error loading either modules (tried in that order): %s" % exc) django.core.exceptions.ImproperlyConfigured: Error loading either
同时,我会基于最流行的后端语言Java来简单的演示下如何使用Either。 什么是Either 在英语中,Either是或的意思,这也是函数式编程风格中Either的意思。 Either是一个对象,它代表有两种可能,或是left,或是right。 但是如果使用Either返回,这意味着方法返回的是一个可以确定的Either对象。 这样本身代码会简洁很多,也会减少处理不同场景的代码复杂度。 而有了Either之后,这意味着你可以保持这种简洁与优雅。 Either来源于何处?
是不是看起来很恶心难于理解,不错是我写的,为了快速上线盈利嘛。在买来的小程序中的js代码还有10层以上的套娃写法,差点改恶心死我了。
Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database
项目地址:https://github.com/milesial/Pytorch-UNet 使用自定义数据报错 报错内容: Either no mask or multiple masks found for the ID {idx}: {mask_file}' AssertionError: Either no mask or multiple masks found for the ID 其实这是个很简单解决了
Error:top-left corner pixel must be either opaque white or transparent. Information:Gradle tasks [:app:assembleDebug] Error:top-left corner pixel must be either opaque white
$ gradle packageDebug --stacktrace error: top-left corner pixel must be either opaque white or transparent error: top-left corner pixel must be either opaque white or transparent.
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either
解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshape(-
如果 list of either 中有 Left,并不能工作。 val erA: Either[String, Int] = Right(1) val erB: Either[String, Int] = Right(2) val erC: Either[String , Int] = Right(3) val elA: Either[String, Int] = Left("error1") val elB: Either[String, Int] = Left [ResponseError[io.circe.Error], NasaData]] 转为了 Either[Throwable, NasaData] val respOfEither2Either: Response[Either[ResponseError[io.circe.Error], NasaData]] => Either[Throwable, NasaData] = resp => {
而fmap定义的行为恰恰是对容器里的内容(值)做映射,完了再装进容器 还有一些特殊的场景,比如Either: data Either a b = Left a | Right b -- Defined in ‘Data.Either’ Either的类型构造器有两个类型参数,而fmap :: (a -> b) -> f a -> f b的f只接受一个参数,所以,Either的fmap要求左边类型固定 Either :: * -> * -> * > :k Either Bool Either Bool :: * -> * > :k Either Bool Int Either Bool Int :: 的Functor实现: > :k Either Either :: * -> * -> * > :t fmap fmap :: Functor f => (a -> b) -> f a -> f b Either b) mapEither f (Left a) = Left a Either a就是个标准的* -> *,例如: > :k Either Int Either Int :: * -> * P.S.也可以对着
我们可以这样做,这就是我们需要引入的一种新类型 - Either类型。 Either 类型是函数式语言中的常见类型,而不是 Java 的一部分。 例如,如果我们有一个 Either 值,那么这个值可以包含 String 类型或 Integer 类型:Either。 下面,你将看到一个 Either 类型的基本实现 。 “提升”抛出已检查异常的函数,并让它返回一个 Either。 所以我个人更喜欢 Either 这种更加灵活的。
同样,我们又可以用Either的Right(Row)来代表成功运算获取了结果Row,用Left(Err)代表运算产生了异常Err。 对于数据库编程我还是选择了Task[Either[E,Option[A]]]这种类型作为数据库操作运算的统一类型。 在Task[Either[E,Option[A]]]这个复合类型中的组成类型Option[A],Either[E,A]实际上是包嵌A类型元素的不同管道,各自可以独立支持Monadic编程,如下: object 当然,这是因为Option,Either是不同的Monad。 //包嵌类型 OptionT[Task,A] => Task[Option[A]] EitherT[Task,A,B] => Task[Either[A,B]] //多层套嵌 Task[Either[
Either:错误处理的类型安全革命传统错误处理的痛点:// 错误信息丢失,无法区分错误类型fun parseUser(json: String): User? (json) } .flatMap { validateUser(it) }private fun validateUser(user: User): Either<UserError, User> { 操作fun processUser(json: String): Either<UserError, ProcessedUser> { return parseUser(json) -> handleError(result.value) is Either.Right -> updateUI(result.value) }}3. (s: String): Either<ParseError, Int> = Either.catch { s.toInt() }.mapLeft { ParseError.NumberFormat