2016-12-06 10 views
1

Наконец-то Scala 2.12 имеет правую предвзятость. Я слышал, что его можно использовать для проверки, но я не могу представить этого. Я не могу найти хороший пример.
Может ли кто-нибудь объяснить мне, как эта монада может помочь мне с проверкой? Кроме того, какие другие варианты использования могут быть покрыты этим улучшенным Либо?Scala validation - Правая правая Либо

+0

Что заставляет вас думать, что 'Either' является« правым предвзятым »? – jwvh

+2

Официальные заметки о выпуске Scala - https://www.scala-lang.org/news/2.12.0 – PawelN

+2

Взгляните на [документацию о 'Either'] (http://typelevel.org/cats/datatypes/either .html) на веб-сайте Cats. –

ответ

5

Either[A, B] Будьте правы предвзято или нет, отлично подходит для проверки/обработки исключений. Правильное смещение облегчает нам работу над ним.

Предположим, мы хотим проверить объект, какие формы могут принимать методы проверки? Простейшая форма будет предикат, метод принимает произвольный объект и возвращая Bool:

sealed trait Base 
case class Foo(I: Int) 
case class Bar(s: String) 

def isValid(b: Base): Bool = b match { 
    case Foo(i) => i > 18 
    case Bar(s) => s.length > 5 
} 

Это будет работать, но не может быть достаточно время от времени. Что, если это пользователь, сталкивающийся с API, и мы хотим быть явным о возможных ошибках с полученным объектом, чтобы пользователь быстро понял, что пошло не так?

Что делать, если вместо возврата Bool мы либо вернем список ошибок, либо вернем действительный объект? Это позволит нам дополнительно составить:

def validate(b: Base): Either[List[String], Base] = b match { 
    case Foo(i) => if (i > 18) Right(b) else Left(List("i must be greater than 18")) 
    case Bar(s) => if (s.length > 5) Right(b) else Left(List("s must be longer than 5 chars")) 
} 

Теперь мы можем отобразить над ним:

val foo = Foo(42) 
val result = validate(foo).map { case Foo(i) => s"yay, valid foo number: $i" } 
result match { 
    case Left(errors) => println(s"Something went wrong: ${errors.mkString(", ")}) 
    case Right(msg) => println(msg) 
} 

Мы получаем две вещи. Во-первых, это способность составлять проверку с другими операциями и откладывать обработку ошибок, а вторая - явные ошибки. Мы могли бы даже сделать это дальше и сделать эти ошибки введенными, позволяя пользователю сопоставлять их и применять обработку ошибок для каждого варианта использования, но это в другое время.

+1

Теперь у меня это есть. Я думал о чем-то более сложном, но я был неправ. Это просто и делает то, что я хочу. Я пытался переоценить свое решение. Благодарю. – PawelN