Functional Programming (10)-Exception handling-either

Source: Internet
Author: User

In the previous section we introduced the new data type option: A data type that can be used to respond to a consistent response when an exception occurs. option allows programmers to ignore what happens after an exception, he only gets a value of none, but the none value is consistent with the type he expects, and he can continue to use the result in a way that handles this type of data. Unfortunately, we can only know that a calculation fails to produce a result by using the None value, but what happens is that option does not provide any hints. In this way, we will not be able to provide users with appropriate system errors or operational error messages.

In this way, we need to add a new data type with extended functionality on the basis of option, so that it can return some exception descriptions: either. It is conceivable that either will return none and include a return value to describe the exception. Then this none of the form becomes the None (e). Let's take a look at Eigher's frame design:

  Trait Either[+e,+a] Case   class Left[+e] (value:e) extends either[e,nothing] case  class Right[+a] (VALUE:A) Extends Either[nothing,a]


The above visible either need to handle two types of E and a:e representing the exception type, and a for the calculation type. As with option, either also has two states: the left represents the inability to complete the calculation, the return value E is a description of the exception condition, and right represents the normal completion of the calculation, and returns the result of a calculation. From the English explanation, either is not right or left. This is known as the "non-union" of types (disjoint union).

This paper presents the implementation of the data type operation function after the basic description of either:

  def map[b] (f:a = B): either[e,b] = This match {case Right (a) + right  (f (a)) case left  (e) and left (e) 
   }  def Flatmap[ee;: E, b] (f:a = Either[ee, b]): Either[ee, b] = This match {case left  (e) + = left  (e)  Case right (a) + f (a)  }  def Orelse[ee;: E, AA;: A] (Default:either[ee, AA]): Either[ee, aa] = this ma tch {Case Left  (_) = = Default case right  (a) = Right (a)  }

Or because either this type of pipe can only save one element, so the implementation of the operation function is straightforward: with the type matching and recursive algorithm on the line.

In the following function we can use a function (A, B) + C to combine two either[a],either[b] into Either[c]:

  Using the recursive algorithm  def map2[ee;: E, B, c] (B:either[ee, b]) (f: (a) = c): Either[ee, C] = (this,b) match {case  (Lef T (e), _) = (e) Case  (_, Left (e)) and left (e) Case  (right (a), right (b)) = + Right (f (a))  }  // with for Comprehensiondef Map2_1[ee;: E, B, c] (B:either[ee, b]) (f: (b) + C): Either[ee, C] = {for {AA <-THISBB <-B} yield f (aa,bb)}//write def Map2_2[ee with Flatmap;: E, B, c] (B:either[ee, b]) (f: (a) = c): Either[ee, C] = {FLA TMap (AA and b map (bb = f (AA,BB)))}


It is not complicated to consider MAP2: because I have only one function (a, b) with lower order =??? , I had to find a way to get that element out of the either pipe and shove it into a new either pipe. Above we have implemented the Map,flatmap we can use for comprehension to implement:

AA <-A:either-remove element from either tube

Yield produces a new either. Map2_1 is the direct notation for comprehension.

Since we have maps and flatmap, we can try to use either:

Case Class Employee (name:string, Age:int, salary:double) for   {age    <-right ()    name <-left ("Invalid name! ")    Salary <-Right (10000.00)  } yield Employee (name,age,salary)               //> res0:ch4.either.either[string, Ch4.either.Employee] = Left (Invalid name!)  For {Age    <-right (<-)    name ("Jonny cash!")    Salary <-Right (10000.00)  } yield Employee (name,age,salary)               //> res1:ch4.either.either[nothing, Ch4.either.Employee] = right (Employee (Jonny                                                  //|  cash!,42,10000.0))

Can be seen in the above three actions (age,name,salary) if any one of the exception left, the result will be left.

Of course, we still have the possibility to calculate a series of either type values, so sequence,traverse these two functions will always be used:

        Using recursive algorithm, using F to upgrade the element to either and then use MAP2 to connect a continuous two elements  def Traverse[e,a,b] (Es:list[a]) (f:a = Either[e, B]): Either[e, LIST[B]] = es match {case Nil + =   Right (Nil) Case   h:: t = = (f (h) map2 traverse (t) (f)) (_:: _)  }  //With Foldright implementation, using F to upgrade the element into a either and then use the MAP2 to connect the successive two elements  def Traverse_1[e,a,b] (Es:list[a]) (f:a = Either[e, B]): either [E, list[b]] = {  es.foldright[either[e, List[b]] (right (Nil)) ((h,t) = f (h). MAP2 (T) (_:: _))  }  def  Sequence[e,a] (Es:list[either[e,a]]): either[e,list[a]] = es match {case  Nil + = Right (Nil) Case  h:: t = = (h map2 sequence (t)) (_ :: _)  }  def Sequence_1[e,a] (Es:list[either[e,a]): either[e,list[a]] = {  traverse (es) (x = x)  }

Here's an example of the actual point:

  Case Class Name (value:string) Case class age (Value:int) case class person (Name:name, age:age) def mkname (name:st Ring): either[string, Name] = {if (name = = "" "| |  name = = null) Left ("Invalid Name") Else Right (name)}//> mkname: (name:string) Ch4.either.either[string,ch4.either.name] def mkage (age:int): either[string,age] = {if (age < 0) L EFT ("Invalid age") Else Right (age)}//> Mkage: (age:int) Ch4.eith Er. Either[string,ch4.either.age] def mkperson (name:string, Age:int): Either[string,person] = {mkname (name). MAP2 (MkAge (A GE)) (person (_,_))}//> Mkperson: (name:string, Age:int) ch4.either.Eit                            Her[string,ch4.either.perso//| N] Mkperson ("Tiger", 18) > Res2:ch4.either.either[string,ch4.either.person] = Right (Name (Tiger                                                  //| ) Mkperson ("Tiger", -18)//> Res3:ch4.either.either[string,ch4.either.person] = Le ft (Invalid Age) Mkperson ("", -1)//> Res4:ch4.either.either[string,ch4.either.person] = Left (Invalid Name)

Mkperson returns right when the input parameter is correct. Any parameter errors are returned to left. However, if all two parameters are wrong, you can only return one of the prompts. We can modify MAP2 to get all the information:

def Map2_s[b, C] (b:either[string, B]) (f: (b) + C): either[string, c] = (this,b) match {case  (left (e), left (EE)) = = Left (e+ee) case (  _, Left (e)) = = Left (e) Case  (left (e:string), _) and left (e) Case  (right (a), right (b) = = right (f (b))  }

Note: We have to make sure that type E is string so we can connect two data because we don't know how to type E. Look at the results after using the new version:

  def mkperson (name:string, Age:int): Either[string,person] = {  mkname (name). map2_s (Mkage) (Person (_,_)  ) }                                               //> Mkperson: (name:string, Age:int) Ch4.either.either[string,ch4.either.perso                                                  //| N]  MkPerson (" Tiger ","                            //> Res2:ch4.either.either[string,ch4.either.person] = right (the Name (Tiger                                                  //|), age (18) ))  Mkperson ("Tiger", -18)                           //> Res3:ch4.either.either[string,ch4.either.person] = left (Invalid)  Mkperson ("", -1)                                 //> Res4:ch4.either.either[string,ch4.either.person] = left (Invalid Nameinvali                                                  

Yes, two messages are connected and returned.


Functional Programming (10)-Exception handling-either

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.