package Ġarrow . core Ċ Ċ import Ġarrow . Kind Ċ import Ġarrow . high er kind Ċ import Ġarrow . type classes . Applic ative Ċ import Ġarrow . type classes . Sem ig roup Ċ Ċ type alias ĠValid ated N el < E , ĠA > Ġ= ĠValid ated < N el < E >, ĠA > Ċ type alias ĠValid < A > Ġ= ĠValid ated . Valid < A > Ċ type alias ĠInvalid < E > Ġ= ĠValid ated . Invalid < E > Ċ Ċ /** Ċ Ġ* Ċ Ġ* Ġan k _ macro _ hierarchy ( arrow . core . Validated ) Ċ Ġ* Ċ Ġ* Ġ{:. begin ner } Ċ Ġ* Ġbegin ner Ċ Ġ* Ċ Ġ* ĠIm ag ine Ġyou Ġare Ġfilling Ġout Ġa Ġweb Ġform Ġto Ġsign Ġup Ġfor Ġan Ġaccount . ĠYou Ġinput Ġyour Ġusername Ġand Ċ Ġ* Ġpassword Ġand Ġsubmit . ĠResponse Ġcomes Ġback Ġsaying Ġyour Ġusername Ġcan 't Ġhave Ġdas hes Ġin Ġit , Ċ Ġ* Ġso Ġyou Ġmake Ġsome Ġchanges Ġand Ġres ub mit . ĠCan 't Ġhave Ġspecial Ġcharacters Ġeither . ĠChange , Ġres ub mit . Ċ Ġ* ĠPassword s Ġneed Ġto Ġhave Ġat Ġleast Ġone Ġcapital Ġletter . ĠChange , Ġres ub mit . ĠPassword Ġneeds Ġto Ġhave Ġat Ġleast Ġone Ġnumber . Ċ Ġ* Ċ Ġ* ĠOr Ġperhaps Ġyou 're Ġreading Ġfrom Ġa Ġconfiguration Ġfile . ĠOne Ġcould Ġimagine Ġthe Ġconfiguration Ġlibrary Ċ Ġ* Ġyou 're Ġusing Ġreturns Ġa Ġ` Try `, Ġor Ġmaybe Ġa Ġ` Either `. ĠYour Ġparsing Ġmay Ġlook Ġsomething Ġlike : Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . core . Either Ċ Ġ* Ġimport Ġarrow . core . Left Ċ Ġ* Ġimport Ġarrow . core . flatMap Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġdata Ġclass ĠConnection Params ( val Ġurl : ĠString , Ġval Ġport : ĠInt ) Ċ Ġ* Ċ Ġ* Ġfun Ġ< A > Ġconfig ( key : ĠString ): ĠEither < String , ĠA > Ġ= ĠLeft ( key ) Ċ Ġ* Ċ Ġ* Ġconfig < String >(" url "). flatMap Ġ{ Ġurl Ġ-> Ċ Ġ* Ġ Ġconfig < Int >(" port "). map Ġ{ ĠConnection Params ( url , Ġit ) Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠYou Ġrun Ġyour Ġprogram Ġand Ġit Ġsays Ġkey Ġ" url " Ġnot Ġfound , Ġturns Ġout Ġthe Ġkey Ġwas Ġ" endpoint ". ĠSo Ċ Ġ* Ġyou Ġchange Ġyour Ġcode Ġand Ġre - run . ĠNow Ġit Ġsays Ġthe Ġ" port " Ġkey Ġwas Ġnot Ġa Ġwell - formed Ġinteger . Ċ Ġ* Ċ Ġ* ĠIt Ġwould Ġbe Ġnice Ġto Ġhave Ġall Ġof Ġthese Ġerrors Ġreported Ġsimultaneously . ĠThat Ġthe Ġusername Ġcan 't Ċ Ġ* Ġhave Ġdas hes Ġcan Ġbe Ġvalidated Ġseparately Ġfrom Ġit Ġnot Ġhaving Ġspecial Ġcharacters , Ġas Ġwell Ġas Ċ Ġ* Ġfrom Ġthe Ġpassword Ġneeding Ġto Ġhave Ġcertain Ġrequirements . ĠA Ġmis spel led Ġ( or Ġmissing ) Ġfield Ġin Ċ Ġ* Ġa Ġconfig Ġcan Ġbe Ġvalidated Ġseparately Ġfrom Ġanother Ġfield Ġnot Ġbeing Ġwell - formed . Ċ Ġ* Ċ Ġ* Ġ# ĠEnter Ġ` Validated `. Ċ Ġ* Ċ Ġ* Ġ## ĠParallel ĠValidation Ċ Ġ* Ċ Ġ* ĠOur Ġgoal Ġis Ġto Ġreport Ġany Ġand Ġall Ġerrors Ġacross Ġindependent Ġbits Ġof Ġdata . ĠFor Ġinstance , Ġwhen Ċ Ġ* Ġwe Ġask Ġfor Ġseveral Ġpieces Ġof Ġconfiguration , Ġeach Ġconfiguration Ġfield Ġcan Ġbe Ġvalidated Ġseparately Ċ Ġ* Ġfrom Ġone Ġanother . ĠHow Ġthen Ġdo Ġwe Ġenforce Ġthat Ġthe Ġdata Ġwe Ġare Ġworking Ġwith Ġis Ġindependent ? Ċ Ġ* ĠWe Ġask Ġfor Ġboth Ġof Ġthem Ġup Ġfront . Ċ Ġ* Ċ Ġ* ĠAs Ġour Ġrunning Ġexample , Ġwe Ġwill Ġlook Ġat Ġconfig Ġparsing . ĠOur Ġconfig Ġwill Ġbe Ġrepresented Ġby Ġa Ċ Ġ* Ġ` Map < String , ĠString >`. ĠParsing Ġwill Ġbe Ġhandled Ġby Ġa Ġ` Read ` Ġtype Ġclass Ġ- Ġwe Ġprovide Ġinstances Ġonly Ċ Ġ* Ġfor Ġ` String ` Ġand Ġ` Int ` Ġfor Ġb rev ity . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . core . None Ċ Ġ* Ġimport Ġarrow . core . Option Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġabstract Ġclass ĠRead < A > Ġ{ Ċ Ġ* Ċ Ġ* Ġabstract Ġfun Ġread ( s : ĠString ): ĠOption < A > Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġstring Read : ĠRead < String > Ġ= Ċ Ġ* ĠĠĠ Ġobject : ĠRead < String >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < String > Ġ= ĠOption ( s ) Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġint Read : ĠRead < Int > Ġ= Ċ Ġ* ĠĠĠ Ġobject : ĠRead < Int >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < Int > Ġ= Ċ Ġ* ĠĠĠĠĠ Ġif Ġ( s . matches ( Regex ("- ?[ 0 - 9 ]+ "))) ĠOption ( s . toInt ()) Ġelse ĠNone Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠThen Ġwe Ġenumerate Ġour Ġerrors âĢĶ when Ġasking Ġfor Ġa Ġconfig Ġvalue , Ġone Ġof Ġtwo Ġthings Ġcan Ġgo Ġwrong : Ċ Ġ* Ġthe Ġfield Ġis Ġmissing , Ġor Ġit Ġis Ġnot Ġwell - formed Ġwith Ġregards Ġto Ġthe Ġexpected Ġtype . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġsealed Ġclass ĠConfig Error Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠMissing Config ( val Ġfield : ĠString ): ĠConfig Error () Ċ Ġ* Ġ Ġdata Ġclass ĠParse Config ( val Ġfield : ĠString ): ĠConfig Error () Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠWe Ġneed Ġa Ġdata Ġtype Ġthat Ġcan Ġrepresent Ġeither Ġa Ġsuccessful Ġvalue Ġ( a Ġparsed Ġconfiguration ), Ġor Ġan Ġerror . Ċ Ġ* ĠIt Ġwould Ġlook Ġlike Ġthe Ġfollowing , Ġwhich ĠArrow Ġprovides Ġin Ġ` arrow . Validated `: Ċ Ġ* Ċ Ġ* Ġ``` kotlin Ċ Ġ* Ġ@ high er kind Ġsealed Ġclass ĠValid ated < out ĠE , Ġout ĠA > Ġ: ĠValid ated Of < E , ĠA > Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠValid < out ĠA >( val Ġa : ĠA ) Ġ: ĠValid ated < Nothing , ĠA >() Ċ Ġ* Ġ Ġdata Ġclass ĠInvalid < out ĠE >( val Ġe : ĠE ) Ġ: ĠValid ated < E , ĠNothing >() Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠNow Ġwe Ġare Ġready Ġto Ġwrite Ġour Ġparser . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . core . None Ċ Ġ* Ġimport Ġarrow . core . Option Ċ Ġ* Ġimport Ġarrow . core . Some Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . valid Ċ Ġ* Ġimport Ġarrow . core . invalid Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġdata Ġclass ĠConfig ( val Ġmap : ĠMap < String , ĠString >) Ġ{ Ċ Ġ* Ġ Ġfun Ġ< A > Ġparse ( read : ĠRead < A >, Ġkey : ĠString ): ĠValid ated < Config Error , ĠA > Ġ{ Ċ Ġ* ĠĠ Ġval Ġv Ġ= ĠOption . from Nullable ( map [ key ]) Ċ Ġ* ĠĠ Ġreturn Ġwhen Ġ( v ) Ġ{ Ċ Ġ* ĠĠĠ Ġis ĠSome Ġ-> Ċ Ġ* ĠĠĠĠ Ġwhen Ġ( val Ġs Ġ= Ġread . read ( v . t )) Ġ{ Ċ Ġ* ĠĠĠĠĠ Ġis ĠSome Ġ-> Ġs . t . valid () Ċ Ġ* ĠĠĠĠĠ Ġis ĠNone Ġ-> ĠConfig Error . Parse Config ( key ). invalid () Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠ Ġis ĠNone Ġ-> ĠValid ated . Invalid ( Config Error . Missing Config ( key )) Ċ Ġ* ĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠEverything Ġis Ġin Ġplace Ġto Ġwrite Ġthe Ġparallel Ġvalidator . ĠRe call Ġthat Ġwe Ġcan Ġonly Ġdo Ġparallel Ċ Ġ* Ġvalidation Ġif Ġeach Ġpiece Ġis Ġindependent . ĠHow Ġdo Ġwe Ġenforce Ġthe Ġdata Ġis Ġindependent ? ĠBy Ċ Ġ* Ġasking Ġfor Ġall Ġof Ġit Ġup Ġfront . ĠLet 's Ġstart Ġwith Ġtwo Ġpieces Ġof Ġdata . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġfun Ġ< E , ĠA , ĠB , ĠC > Ġparallel Validate ( v 1 : ĠValid ated < E , ĠA >, Ġv 2 : ĠValid ated < E , ĠB >, Ġf : Ġ( A , ĠB ) Ġ-> ĠC ): ĠValid ated < E , ĠC > Ġ{ Ċ Ġ* Ġ Ġreturn Ġwhen Ġ{ Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> ĠValid ated . Valid ( f ( v 1 . a , Ġv 2 . a )) Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> Ġv 2 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> Ġv 1 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> ĠTODO () Ċ Ġ* ĠĠ Ġelse Ġ-> ĠTODO () Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠWe 've Ġrun Ġinto Ġa Ġproblem . ĠIn Ġthe Ġcase Ġwhere Ġboth Ġhave Ġerrors , ĠWe Ġwant Ġto Ġreport Ġboth . Ġwe Ċ Ġ* Ġdon 't Ġhave Ġa Ġway Ġto Ġcombine ĠConfig Errors . ĠBut Ġas Ġclients , Ġwe Ġcan Ġchange Ġour ĠValid ated Ċ Ġ* Ġvalues Ġwhere Ġthe Ġerror Ġcan Ġbe Ġcombined , Ġsay , Ġa Ġ` List < Config Error >`. We Ġare Ġgoing Ġto Ġuse Ġa Ċ Ġ* Ġ` Non Empty List < Config Error >` âĢĶ the ĠNon Empty List Ġstatic ally Ġguarantees Ġwe Ġhave Ġat Ġleast Ġone Ġvalue , Ċ Ġ* Ġwhich Ġalign s Ġwith Ġthe Ġfact Ġthat Ġif Ġwe Ġhave Ġan ĠInvalid , Ġthen Ġwe Ġmost Ġcertainly Ġhave Ġat Ġleast Ġone Ġerror . Ċ Ġ* ĠThis Ġtechnique Ġis Ġso Ġcommon Ġthere Ġis Ġa Ġconvenient Ġmethod Ġon Ġ` Validated ` Ġcalled Ġ` to Validated N el ` Ċ Ġ* Ġthat Ġturns Ġany Ġ` Validated < E , ĠA >` Ġvalue Ġto Ġa Ġ` Validated < Non Empty List < E >, ĠA >`. ĠAdditionally , Ġthe Ċ Ġ* Ġtype Ġalias Ġ` Validated N el < E , ĠA >` Ġis Ġprovided . Ċ Ġ* Ċ Ġ* ĠTime Ġto Ġparse . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . core . Non Empty List Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġfun Ġ< E , ĠA , ĠB , ĠC > Ġparallel Validate Ċ Ġ* ĠĠ Ġ( v 1 : ĠValid ated < E , ĠA >, Ġv 2 : ĠValid ated < E , ĠB >, Ġf : Ġ( A , ĠB ) Ġ-> ĠC ): ĠValid ated < Non Empty List < E >, ĠC > Ġ= Ċ Ġ* Ġ Ġwhen Ġ{ Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> ĠValid ated . Valid ( f ( v 1 . a , Ġv 2 . a )) Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> Ġv 2 . to Validated N el () Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> Ġv 1 . to Validated N el () Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> ĠValid ated . Invalid ( Non Empty List ( v 1 . e , ĠlistOf ( v 2 . e ))) Ċ Ġ* ĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Not Ġpossible Ġvalue ") Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠKotlin Ġsays Ġthat Ġour Ġmatch Ġis Ġnot Ġex haustive Ġand Ġwe Ġhave Ġto Ġadd Ġ` else `. Ċ Ġ* Ċ Ġ* ĠWhen Ġno Ġerrors Ġare Ġpresent Ġin Ġthe Ġconfiguration , Ġwe Ġget Ġa Ġ` Connection Params ` Ġwrapped Ġin Ġa Ġ` Valid ` Ġinstance . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : playground Ċ Ġ* Ġimport Ġarrow . core . None Ċ Ġ* Ġimport Ġarrow . core . Option Ċ Ġ* Ġimport Ġarrow . core . Some Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . valid Ċ Ġ* Ġimport Ġarrow . core . invalid Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠConnection Params ( val Ġurl : ĠString , Ġval Ġport : ĠInt ) Ċ Ġ* Ċ Ġ* Ġabstract Ġclass ĠRead < A > Ġ{ Ċ Ġ* Ġ Ġabstract Ġfun Ġread ( s : ĠString ): ĠOption < A > Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġstring Read : ĠRead < String > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < String >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < String > Ġ= ĠOption ( s ) Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġint Read : ĠRead < Int > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < Int >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < Int > Ġ= Ċ Ġ* ĠĠĠĠĠ Ġif Ġ( s . matches ( Regex ("- ?[ 0 - 9 ]+ "))) ĠOption ( s . toInt ()) Ġelse ĠNone Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠConfig Error Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠMissing Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ Ġdata Ġclass ĠParse Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠConfig ( val Ġmap : ĠMap < String , ĠString >) Ġ{ Ċ Ġ* Ġ Ġfun Ġ< A > Ġparse ( read : ĠRead < A >, Ġkey : ĠString ): ĠValid ated < Config Error , ĠA > Ġ{ Ċ Ġ* ĠĠ Ġval Ġv Ġ= ĠOption . from Nullable ( map [ key ]) Ċ Ġ* ĠĠ Ġreturn Ġwhen Ġ( v ) Ġ{ Ċ Ġ* ĠĠĠ Ġis ĠSome Ġ-> Ċ Ġ* ĠĠĠĠ Ġwhen Ġ( val Ġs Ġ= Ġread . read ( v . t )) Ġ{ Ċ Ġ* ĠĠĠĠĠ Ġis ĠSome Ġ-> Ġs . t . valid () Ċ Ġ* ĠĠĠĠĠ Ġis ĠNone Ġ-> ĠConfig Error . Parse Config ( key ). invalid () Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠ Ġis ĠNone Ġ-> ĠValid ated . Invalid ( Config Error . Missing Config ( key )) Ċ Ġ* ĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġfun Ġ< E , ĠA , ĠB , ĠC > Ġparallel Validate ( v 1 : ĠValid ated < E , ĠA >, Ġv 2 : ĠValid ated < E , ĠB >, Ġf : Ġ( A , ĠB ) Ġ-> ĠC ): ĠValid ated < E , ĠC > Ġ{ Ċ Ġ* Ġ Ġreturn Ġwhen Ġ{ Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> ĠValid ated . Valid ( f ( v 1 . a , Ġv 2 . a )) Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> Ġv 2 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> Ġv 1 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> ĠTODO () Ċ Ġ* ĠĠ Ġelse Ġ-> ĠTODO () Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġ Ġval Ġconfig Ġ= ĠConfig ( map Of (" url " Ġto Ġ" 1 2 7 . 0 . 0 . 1 ", Ġ" port " Ġto Ġ" 1 3 3 7 ")) Ċ Ġ* Ċ Ġ* Ġ Ġval Ġvalid Ġ= Ġparallel Validate ( Ċ Ġ* Ġ Ġconfig . parse ( Read . string Read , Ġ" url "), Ċ Ġ* Ġ Ġconfig . parse ( Read . int Read , Ġ" port ") Ċ Ġ* Ġ Ġ) Ġ{ Ġurl , Ġport Ġ-> ĠConnection Params ( url , Ġport ) Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġfun Ġmain () Ġ{ Ċ Ġ* Ġ Ġprintln (" valid Ġ= Ġ$ valid ") Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* ĠBut Ġwhat Ġhappens Ġwhen Ġhaving Ġone Ġor Ġmore Ġerrors ? ĠThey Ġare Ġaccumulated Ġin Ġa Ġ` Non Empty List ` Ġwrapped Ġin Ċ Ġ* Ġan Ġ` Invalid ` Ġinstance . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : playground Ċ Ġ* Ġimport Ġarrow . core . None Ċ Ġ* Ġimport Ġarrow . core . Option Ċ Ġ* Ġimport Ġarrow . core . Some Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . valid Ċ Ġ* Ġimport Ġarrow . core . invalid Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠConnection Params ( val Ġurl : ĠString , Ġval Ġport : ĠInt ) Ċ Ġ* Ċ Ġ* Ġabstract Ġclass ĠRead < A > Ġ{ Ċ Ġ* Ġ Ġabstract Ġfun Ġread ( s : ĠString ): ĠOption < A > Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġstring Read : ĠRead < String > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < String >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < String > Ġ= ĠOption ( s ) Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġint Read : ĠRead < Int > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < Int >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < Int > Ġ= Ċ Ġ* ĠĠĠĠĠ Ġif Ġ( s . matches ( Regex ("- ?[ 0 - 9 ]+ "))) ĠOption ( s . toInt ()) Ġelse ĠNone Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠConfig Error Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠMissing Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ Ġdata Ġclass ĠParse Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠConfig ( val Ġmap : ĠMap < String , ĠString >) Ġ{ Ċ Ġ* Ġ Ġfun Ġ< A > Ġparse ( read : ĠRead < A >, Ġkey : ĠString ): ĠValid ated < Config Error , ĠA > Ġ{ Ċ Ġ* ĠĠ Ġval Ġv Ġ= ĠOption . from Nullable ( map [ key ]) Ċ Ġ* ĠĠ Ġreturn Ġwhen Ġ( v ) Ġ{ Ċ Ġ* ĠĠĠ Ġis ĠSome Ġ-> Ċ Ġ* ĠĠĠĠ Ġwhen Ġ( val Ġs Ġ= Ġread . read ( v . t )) Ġ{ Ċ Ġ* ĠĠĠĠĠ Ġis ĠSome Ġ-> Ġs . t . valid () Ċ Ġ* ĠĠĠĠĠ Ġis ĠNone Ġ-> ĠConfig Error . Parse Config ( key ). invalid () Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠ Ġis ĠNone Ġ-> ĠValid ated . Invalid ( Config Error . Missing Config ( key )) Ċ Ġ* ĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġfun Ġ< E , ĠA , ĠB , ĠC > Ġparallel Validate ( v 1 : ĠValid ated < E , ĠA >, Ġv 2 : ĠValid ated < E , ĠB >, Ġf : Ġ( A , ĠB ) Ġ-> ĠC ): ĠValid ated < E , ĠC > Ġ{ Ċ Ġ* Ġ Ġreturn Ġwhen Ġ{ Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> ĠValid ated . Valid ( f ( v 1 . a , Ġv 2 . a )) Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Valid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> Ġv 2 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Valid Ġ-> Ġv 1 Ċ Ġ* ĠĠ Ġv 1 Ġis ĠValid ated . Invalid Ġ&& Ġv 2 Ġis ĠValid ated . Invalid Ġ-> ĠTODO () Ċ Ġ* ĠĠ Ġelse Ġ-> ĠTODO () Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġval Ġconfig Ġ= ĠConfig ( map Of (" url " Ġto Ġ" 1 2 7 . 0 . 0 . 1 ", Ġ" port " Ġto Ġ" not Ġa Ġnumber ")) Ċ Ġ* Ċ Ġ* Ġval Ġvalid Ġ= Ġparallel Validate ( Ċ Ġ* Ġ Ġconfig . parse ( Read . string Read , Ġ" url "), Ċ Ġ* Ġ Ġconfig . parse ( Read . int Read , Ġ" port ") Ċ Ġ* Ġ Ġ) Ġ{ Ġurl , Ġport Ġ-> ĠConnection Params ( url , Ġport ) Ġ} Ċ Ġ* Ġ Ġ// sample End Ċ Ġ* Ġfun Ġmain () Ġ{ Ċ Ġ* Ġ Ġprintln (" valid Ġ= Ġ$ valid ") Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* Ġ## ĠSequential ĠValidation Ċ Ġ* Ċ Ġ* ĠIf Ġyou Ġdo Ġwant Ġerror Ġaccum ulation Ġbut Ġoccasion ally Ġrun Ġinto Ġplaces Ġwhere Ġsequential Ġvalidation Ġis Ġneeded , Ċ Ġ* Ġthen ĠValid ated Ġprovides Ġ` with Either ` Ġmethod Ġto Ġallow Ġyou Ġto Ġtemporarily Ġturn Ġa ĠValid ated Ċ Ġ* Ġinstance Ġinto Ġan ĠEither Ġinstance Ġand Ġapply Ġit Ġto Ġa Ġfunction . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : playground Ċ Ġ* Ġimport Ġarrow . core . Either Ċ Ġ* Ġimport Ġarrow . core . flatMap Ċ Ġ* Ġimport Ġarrow . core . left Ċ Ġ* Ġimport Ġarrow . core . None Ċ Ġ* Ġimport Ġarrow . core . Option Ċ Ġ* Ġimport Ġarrow . core . right Ċ Ġ* Ġimport Ġarrow . core . Some Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . valid Ċ Ġ* Ġimport Ġarrow . core . invalid Ċ Ġ* Ċ Ġ* Ġabstract Ġclass ĠRead < A > Ġ{ Ċ Ġ* Ġ Ġabstract Ġfun Ġread ( s : ĠString ): ĠOption < A > Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġstring Read : ĠRead < String > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < String >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < String > Ġ= ĠOption ( s ) Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ċ Ġ* ĠĠ Ġval Ġint Read : ĠRead < Int > Ġ= Ċ Ġ* ĠĠĠ Ġobject Ġ: ĠRead < Int >() Ġ{ Ċ Ġ* ĠĠĠĠ Ġoverride Ġfun Ġread ( s : ĠString ): ĠOption < Int > Ġ= Ċ Ġ* ĠĠĠĠĠ Ġif Ġ( s . matches ( Regex ("- ?[ 0 - 9 ]+ "))) ĠOption ( s . toInt ()) Ġelse ĠNone Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠConfig ( val Ġmap : ĠMap < String , ĠString >) Ġ{ Ċ Ġ* Ġ Ġfun Ġ< A > Ġparse ( read : ĠRead < A >, Ġkey : ĠString ): ĠValid ated < Config Error , ĠA > Ġ{ Ċ Ġ* ĠĠ Ġval Ġv Ġ= ĠOption . from Nullable ( map [ key ]) Ċ Ġ* ĠĠ Ġreturn Ġwhen Ġ( v ) Ġ{ Ċ Ġ* ĠĠĠ Ġis ĠSome Ġ-> Ċ Ġ* ĠĠĠĠ Ġwhen Ġ( val Ġs Ġ= Ġread . read ( v . t )) Ġ{ Ċ Ġ* ĠĠĠĠĠ Ġis ĠSome Ġ-> Ġs . t . valid () Ċ Ġ* ĠĠĠĠĠ Ġis ĠNone Ġ-> ĠConfig Error . Parse Config ( key ). invalid () Ċ Ġ* ĠĠĠĠ Ġ} Ċ Ġ* ĠĠĠ Ġis ĠNone Ġ-> ĠValid ated . Invalid ( Config Error . Missing Config ( key )) Ċ Ġ* ĠĠ Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġsealed Ġclass ĠConfig Error Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠMissing Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ Ġdata Ġclass ĠParse Config ( val Ġfield : ĠString ) Ġ: ĠConfig Error () Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġfun Ġpositive ( field : ĠString , Ġi : ĠInt ): ĠEither < Config Error , ĠInt > Ġ{ Ċ Ġ* Ġ Ġreturn Ġif Ġ( i Ġ>= Ġ 0 ) Ġi . right () Ċ Ġ* Ġ Ġelse ĠConfig Error . Parse Config ( field ). left () Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġval Ġconfig Ġ= ĠConfig ( map Of (" house _ number " Ġto Ġ"- 4 2 ")) Ċ Ġ* Ċ Ġ* Ġval Ġhouse Number Ġ= Ġconfig . parse ( Read . int Read , Ġ" house _ number "). with Either Ġ{ Ġeither Ġ-> Ċ Ġ* Ġ Ġeither . flatMap Ġ{ Ġpositive (" house _ number ", Ġit ) Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġfun Ġmain () Ġ{ Ċ Ġ* Ġ Ġprintln ( house Number ) Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* Ġ## ĠAltern ative Ġvalidation Ġstrategies Ġto ĠValid ated : Ġusing Ġ` Applic ative Error ` Ċ Ġ* Ċ Ġ* ĠWe Ġmay Ġuse Ġ` Applic ative Error ` Ġinstead Ġof Ġ` Validated ` Ġto Ġabstract Ġaway Ġvalidation Ġstrategies Ġand Ġraising Ġerrors Ġin Ġthe Ġcontext Ġwe Ġare Ġcomputing Ġin . Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank Ċ Ġ* Ġimport Ġarrow . Kind Ċ Ġ* Ġimport Ġarrow . core . Either Ċ Ġ* Ġimport Ġarrow . core . Either Partial Of Ċ Ġ* Ġimport Ġarrow . core . N el Ċ Ġ* Ġimport Ġarrow . core . Non Empty List Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . Validated Partial Of Ċ Ġ* Ġimport Ġarrow . core . nel Ċ Ġ* Ġimport Ġarrow . type classes . Applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . validated . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . either . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . none mpty list . sem ig roup . sem ig roup Ċ Ġ* Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġsealed Ġclass ĠValidationError ( val Ġmsg : ĠString ) Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠDoes Not Contain ( val Ġvalue : ĠString ) Ġ: ĠValidationError (" Did Ġnot Ġcontain Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠMax Length ( val Ġvalue : ĠInt ) Ġ: ĠValidationError (" Exceeded Ġlength Ġof Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠNot An Email ( val Ġreasons : ĠN el < ValidationError >) Ġ: ĠValidationError (" Not Ġa Ġvalid Ġemail ") Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠForm Field ( val Ġlabel : ĠString , Ġval Ġvalue : ĠString ) Ċ Ġ* Ġdata Ġclass ĠEmail ( val Ġvalue : ĠString ) Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠRules < F >( A : ĠApplic ative Error < F , ĠN el < ValidationError >>) Ġ: ĠApplic ative Error < F , ĠN el < ValidationError >> Ġby ĠA Ġ{ Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . contains ( needle : ĠString ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . contains ( needle , Ġfalse )) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . DoesNot Contain ( needle ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . maxLength ( maxLength : ĠInt ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . length Ġ<= ĠmaxLength ) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . MaxLength ( maxLength ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġfun ĠForm Field . validate Email (): ĠKind < F , ĠEmail > Ġ= Ċ Ġ* ĠĠ Ġmap ( contains ("@ "), ĠmaxLength ( 2 5 0 ), Ġ{ Ċ Ġ* ĠĠĠ ĠEmail ( value ) Ċ Ġ* ĠĠ Ġ}). handleError With Ġ{ Ġraise Error ( ValidationError . Not An Email ( it ). nel ()) Ġ} Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠError Accum ulation Strategy Ġ: Ċ Ġ* ĠĠĠ ĠRules < Validated Partial Of < N el < ValidationError >> >( Validated . applic ative Error ( Non Empty List . sem ig roup ())) Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠFail Fast Strategy Ġ: Ċ Ġ* ĠĠ ĠRules < Either Partial Of < N el < ValidationError >> >( Either . applic ative Error ()) Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġfail Fast ( f : ĠFail Fast Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Fail Fast Strategy ) Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġaccum ulate Errors ( f : ĠError Accum ulation Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Error Accum ulation Strategy ) Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* Ġ` Rules ` Ġdefines Ġabstract Ġbehaviors Ġthat Ġcan Ġbe Ġcomposed Ġand Ġhave Ġaccess Ġto Ġthe Ġscope Ġof Ġ` Applic ative Error ` Ġwhere Ġwe Ġcan Ġinvoke Ġ` just ` Ġto Ġlift Ġvalues Ġin Ġto Ġthe Ġpositive Ġresult Ġand Ġ` raise Error ` Ġinto Ġthe Ġerror Ġcontext . Ċ Ġ* Ċ Ġ* ĠOnce Ġwe Ġhave Ġsuch Ġabstract Ġalgebra Ġdefined Ġwe Ġcan Ġsimply Ġmaterial ize Ġit Ġto Ġdata Ġtypes Ġthat Ġsupport Ġdifferent Ġerror Ġstrategies : Ċ Ġ* Ċ Ġ* Ġ Ġ* Error Ġaccum ulation * Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : playground Ċ Ġ* Ġimport Ġarrow . Kind Ċ Ġ* Ġimport Ġarrow . core . Either Ċ Ġ* Ġimport Ġarrow . core . Either Partial Of Ċ Ġ* Ġimport Ġarrow . core . N el Ċ Ġ* Ġimport Ġarrow . core . Non Empty List Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . Validated Partial Of Ċ Ġ* Ġimport Ġarrow . core . nel Ċ Ġ* Ġimport Ġarrow . type classes . Applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . validated . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . either . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . none mpty list . sem ig roup . sem ig roup Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠValidationError ( val Ġmsg : ĠString ) Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠDoes Not Contain ( val Ġvalue : ĠString ) Ġ: ĠValidationError (" Did Ġnot Ġcontain Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠMax Length ( val Ġvalue : ĠInt ) Ġ: ĠValidationError (" Exceeded Ġlength Ġof Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠNot An Email ( val Ġreasons : ĠN el < ValidationError >) Ġ: ĠValidationError (" Not Ġa Ġvalid Ġemail ") Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠForm Field ( val Ġlabel : ĠString , Ġval Ġvalue : ĠString ) Ċ Ġ* Ġdata Ġclass ĠEmail ( val Ġvalue : ĠString ) Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠRules < F >( A : ĠApplic ative Error < F , ĠN el < ValidationError >>) Ġ: ĠApplic ative Error < F , ĠN el < ValidationError >> Ġby ĠA Ġ{ Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . contains ( needle : ĠString ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . contains ( needle , Ġfalse )) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . DoesNot Contain ( needle ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . maxLength ( maxLength : ĠInt ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . length Ġ<= ĠmaxLength ) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . MaxLength ( maxLength ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġfun ĠForm Field . validate Email (): ĠKind < F , ĠEmail > Ġ= Ċ Ġ* ĠĠ Ġmap ( contains ("@ "), ĠmaxLength ( 2 5 0 ), Ġ{ Ċ Ġ* ĠĠĠ ĠEmail ( value ) Ċ Ġ* ĠĠ Ġ}). handleError With Ġ{ Ġraise Error ( ValidationError . Not An Email ( it ). nel ()) Ġ} Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠError Accum ulation Strategy Ġ: Ċ Ġ* ĠĠĠ ĠRules < Validated Partial Of < N el < ValidationError >> >( Validated . applic ative Error ( Non Empty List . sem ig roup ())) Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠFail Fast Strategy Ġ: Ċ Ġ* ĠĠ ĠRules < Either Partial Of < N el < ValidationError >> >( Either . applic ative Error ()) Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġfail Fast ( f : ĠFail Fast Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Fail Fast Strategy ) Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġaccum ulate Errors ( f : ĠError Accum ulation Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Error Accum ulation Strategy ) Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġval Ġvalue Ġ= Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġ ĠRules Ġaccum ulate Errors Ġ{ Ċ Ġ* ĠĠĠ ĠlistOf ( Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Invalid ĠEmail ĠDomain ĠLabel ", Ġ" now here . com "), Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Too ĠLong ĠEmail ĠLabel ", Ġ" now her et ool ong ${ ( 0 .. 2 5 1 ). map Ġ{ Ġ" g " Ġ}} "), Ġ// this Ġacc umul ates ĠN Ġerrors Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Valid ĠEmail ĠLabel ", Ġ" get lost @ now here . com ") Ċ Ġ* ĠĠĠ Ġ). map Ġ{ Ġit . validate Email () Ġ} Ċ Ġ* ĠĠĠ Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġfun Ġmain () Ġ{ Ċ Ġ* Ġ Ġprintln ( value ) Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ġ Ġ* Fail ĠFast * Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : playground Ċ Ġ* Ġimport Ġarrow . Kind Ċ Ġ* Ġimport Ġarrow . core . Either Ċ Ġ* Ġimport Ġarrow . core . Either Partial Of Ċ Ġ* Ġimport Ġarrow . core . N el Ċ Ġ* Ġimport Ġarrow . core . Non Empty List Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ġimport Ġarrow . core . Validated Partial Of Ċ Ġ* Ġimport Ġarrow . core . nel Ċ Ġ* Ġimport Ġarrow . type classes . Applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . validated . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . either . applic ative Error . applic ative Error Ċ Ġ* Ġimport Ġarrow . core . extensions . none mpty list . sem ig roup . sem ig roup Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠValidationError ( val Ġmsg : ĠString ) Ġ{ Ċ Ġ* Ġ Ġdata Ġclass ĠDoes Not Contain ( val Ġvalue : ĠString ) Ġ: ĠValidationError (" Did Ġnot Ġcontain Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠMax Length ( val Ġvalue : ĠInt ) Ġ: ĠValidationError (" Exceeded Ġlength Ġof Ġ$ value ") Ċ Ġ* Ġ Ġdata Ġclass ĠNot An Email ( val Ġreasons : ĠN el < ValidationError >) Ġ: ĠValidationError (" Not Ġa Ġvalid Ġemail ") Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġdata Ġclass ĠForm Field ( val Ġlabel : ĠString , Ġval Ġvalue : ĠString ) Ċ Ġ* Ġdata Ġclass ĠEmail ( val Ġvalue : ĠString ) Ċ Ġ* Ċ Ġ* Ġsealed Ġclass ĠRules < F >( A : ĠApplic ative Error < F , ĠN el < ValidationError >>) Ġ: ĠApplic ative Error < F , ĠN el < ValidationError >> Ġby ĠA Ġ{ Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . contains ( needle : ĠString ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . contains ( needle , Ġfalse )) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . DoesNot Contain ( needle ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġprivate Ġfun ĠForm Field . maxLength ( maxLength : ĠInt ): ĠKind < F , ĠForm Field > Ġ= Ċ Ġ* ĠĠ Ġif Ġ( value . length Ġ<= ĠmaxLength ) Ġjust ( this ) Ċ Ġ* ĠĠ Ġelse Ġraise Error ( ValidationError . MaxLength ( maxLength ). nel ()) Ċ Ġ* Ċ Ġ* Ġ Ġfun ĠForm Field . validate Email (): ĠKind < F , ĠEmail > Ġ= Ċ Ġ* ĠĠ Ġmap ( contains ("@ "), ĠmaxLength ( 2 5 0 ), Ġ{ Ċ Ġ* ĠĠĠ ĠEmail ( value ) Ċ Ġ* ĠĠ Ġ}). handleError With Ġ{ Ġraise Error ( ValidationError . Not An Email ( it ). nel ()) Ġ} Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠError Accum ulation Strategy Ġ: Ċ Ġ* ĠĠĠ ĠRules < Validated Partial Of < N el < ValidationError >> >( Validated . applic ative Error ( Non Empty List . sem ig roup ())) Ċ Ġ* Ċ Ġ* Ġ Ġobject ĠFail Fast Strategy Ġ: Ċ Ġ* ĠĠ ĠRules < Either Partial Of < N el < ValidationError >> >( Either . applic ative Error ()) Ċ Ġ* Ċ Ġ* Ġ Ġcompanion Ġobject Ġ{ Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġfail Fast ( f : ĠFail Fast Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Fail Fast Strategy ) Ċ Ġ* ĠĠ Ġin fix Ġfun Ġ< A > Ġaccum ulate Errors ( f : ĠError Accum ulation Strategy . () Ġ-> ĠA ): ĠA Ġ= Ġf ( Error Accum ulation Strategy ) Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġval Ġvalue Ġ= Ċ Ġ* Ġ// sample Start Ċ Ġ* Ġ ĠRules Ġfail Fast Ġ{ Ċ Ġ* ĠĠĠ ĠlistOf ( Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Invalid ĠEmail ĠDomain ĠLabel ", Ġ" now here . com "), Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Too ĠLong ĠEmail ĠLabel ", Ġ" now her et ool ong ${ ( 0 .. 2 5 1 ). map Ġ{ Ġ" g " Ġ}} "), Ġ// this Ġfails Ġfast Ċ Ġ* ĠĠĠĠĠ ĠForm Field (" Valid ĠEmail ĠLabel ", Ġ" get lost @ now here . com ") Ċ Ġ* ĠĠĠ Ġ). map Ġ{ Ġit . validate Email () Ġ} Ċ Ġ* Ġ Ġ} Ċ Ġ* Ġ// sample End Ċ Ġ* Ġfun Ġmain () Ġ{ Ċ Ġ* Ġ Ġprintln ( value ) Ċ Ġ* Ġ} Ċ Ġ* Ġ``` Ċ Ġ* Ċ Ġ* Ġ### ĠSupported Ġtype Ġclasses Ċ Ġ* Ċ Ġ* Ġ``` kotlin : ank : replace Ċ Ġ* Ġimport Ġarrow . reflect . DataType Ċ Ġ* Ġimport Ġarrow . reflect . tc Markdown List Ċ Ġ* Ġimport Ġarrow . core . Validated Ċ Ġ* Ċ Ġ* ĠDataType ( Validated :: class ). tc Markdown List () Ċ Ġ* Ġ``` Ċ Ġ*/ Ċ @ high er kind Ċ sealed Ġclass ĠValid ated < out ĠE , Ġout ĠA > Ġ: ĠValid ated Of < E , ĠA > Ġ{ ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠ Ġfun Ġ< E , ĠA > Ġinvalid N el ( e : ĠE ): ĠValid ated N el < E , ĠA > Ġ= ĠInvalid ( Non Empty List ( e , ĠlistOf ())) ĊĊĠĠĠ Ġfun Ġ< E , ĠA > Ġvalid N el ( a : ĠA ): ĠValid ated N el < E , ĠA > Ġ= ĠValid ( a ) ĊĊĠĠĠ Ġ@ Deprecated ( ĊĠĠĠĠĠ Ġ" Try Ġwill Ġbe Ġdeleted Ġsoon Ġas Ġit Ġprom otes Ġeager Ġexecution Ġof Ġeffects , Ġso Ġit âĢĻ s Ġbetter Ġif Ġyou Ġwork Ġwith ĠEither âĢĻ s Ġsuspend Ġconstructors Ġor Ġa Ġan Ġeffect Ġhandler Ġlike ĠIO ", ĊĠĠĠĠĠ ĠReplace With (" from Either ( t )") ĊĠĠĠ Ġ) ĊĠĠĠ Ġfun Ġ< A > Ġfrom Try ( t : ĠTry < A >): ĠValid ated < Throwable , ĠA > Ġ= Ġt . fold ({ ĠInvalid ( it ) Ġ}, Ġ{ ĠValid ( it ) Ġ}) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConverts Ġan Ġ` Either < A , ĠB >` Ġto Ġan Ġ` Validated < A , ĠB >`. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< E , ĠA > Ġfrom Either ( e : ĠEither < E , ĠA >): ĠValid ated < E , ĠA > Ġ= Ġe . fold ({ ĠInvalid ( it ) Ġ}, Ġ{ ĠValid ( it ) Ġ}) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConverts Ġan Ġ` Option < B >` Ġto Ġan Ġ` Validated < A , ĠB >`, Ġwhere Ġthe Ġprovided Ġ` if None ` Ġvalues Ġis Ġreturned Ġon ĊĠĠĠĠ Ġ* Ġthe Ġinvalid Ġof Ġthe Ġ` Validated ` Ġwhen Ġthe Ġspecified Ġ` Option ` Ġis Ġ` None `. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< E , ĠA > Ġfrom Option ( o : ĠOption < A >, Ġif None : Ġ() Ġ-> ĠE ): ĠValid ated < E , ĠA > Ġ= ĊĠĠĠĠĠ Ġo . fold ( ĊĠĠĠĠĠĠĠ Ġ{ ĠInvalid ( if None ()) Ġ}, ĊĠĠĠĠĠĠĠ Ġ{ ĠValid ( it ) Ġ} ĊĠĠĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġdata Ġclass ĠValid < out ĠA >( val Ġa : ĠA ) Ġ: ĠValid ated < Nothing , ĠA >() ĊĊĠ Ġdata Ġclass ĠInvalid < out ĠE >( val Ġe : ĠE ) Ġ: ĠValid ated < E , ĠNothing >() ĊĊĠ Ġinline Ġfun Ġ< B > Ġfold ( fe : Ġ( E ) Ġ-> ĠB , Ġfa : Ġ( A ) Ġ-> ĠB ): ĠB Ġ= ĊĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠ Ġis ĠValid Ġ-> Ġfa ( a ) ĊĠĠĠĠĠ Ġis ĠInvalid Ġ-> Ġ( fe ( e )) ĊĠĠĠ Ġ} ĊĊĠ Ġval ĠisValid Ġ= ĊĠĠĠ Ġfold ({ Ġfalse Ġ}, Ġ{ Ġtrue Ġ}) ĊĠ Ġval Ġis Invalid Ġ= ĊĠĠĠ Ġfold ({ Ġtrue Ġ}, Ġ{ Ġfalse Ġ}) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠIs Ġthis ĠValid Ġand Ġmatching Ġthe Ġgiven Ġpredicate ĊĠĠ Ġ*/ ĊĠ Ġfun Ġexist ( predicate : Ġ( A ) Ġ-> ĠBoolean ): ĠBoolean Ġ= Ġfold ({ Ġfalse Ġ}, Ġ{ Ġpredicate ( it ) Ġ}) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠConverts Ġthe Ġvalue Ġto Ġan ĠEither < E , ĠA > ĊĠĠ Ġ*/ ĊĠ Ġfun Ġto Either (): ĠEither < E , ĠA > Ġ= Ġfold ({ ĠLeft ( it ) Ġ}, Ġ{ ĠRight ( it ) Ġ}) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠReturns ĠValid Ġvalues Ġwrapped Ġin ĠSome , Ġand ĠNone Ġfor ĠInvalid Ġvalues ĊĠĠ Ġ*/ ĊĠ Ġfun Ġto Option (): ĠOption < A > Ġ= Ġfold ({ ĠNone Ġ}, Ġ{ ĠSome ( it ) Ġ}) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠConvert Ġthis Ġvalue Ġto Ġa Ġsingle Ġelement ĠList Ġif Ġit Ġis ĠValid , ĊĠĠ Ġ* Ġotherwise Ġreturn Ġan Ġempty ĠList ĊĠĠ Ġ*/ ĊĠ Ġfun Ġto List (): ĠList < A > Ġ= Ġfold ({ ĠlistOf () Ġ}, Ġ{ ĠlistOf ( it ) Ġ}) ĊĊĠ Ġ/** ĠLift Ġthe ĠInvalid Ġvalue Ġinto Ġa ĠNon Empty List . Ġ*/ ĊĠ Ġfun Ġto Validated N el (): ĠValid ated N el < E , ĠA > Ġ= ĊĠĠĠ Ġfold ( ĊĠĠĠĠĠ Ġ{ Ġinvalid N el ( it ) Ġ}, ĊĠĠĠĠĠ Ġ{ ĠValid ( it ) Ġ} ĊĠĠĠ Ġ) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠConvert Ġto Ġan ĠEither , Ġapply Ġa Ġfunction , Ġconvert Ġback . ĠThis Ġis Ġhandy ĊĠĠ Ġ* Ġwhen Ġyou Ġwant Ġto Ġuse Ġthe ĠMonad ic Ġproperties Ġof Ġthe ĠEither Ġtype . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< EE , ĠB > Ġwith Either ( f : Ġ( Either < E , ĠA >) Ġ-> ĠEither < EE , ĠB >): ĠValid ated < EE , ĠB > Ġ= Ġfrom Either ( f ( to Either ())) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠValid ated Ġis Ġa Ġ[ functor . B if un ctor ], Ġthis Ġmethod Ġapplies Ġone Ġof Ġthe ĊĠĠ Ġ* Ġgiven Ġfunctions . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< EE , ĠAA > Ġb imap ( fe : Ġ( E ) Ġ-> ĠEE , Ġfa : Ġ( A ) Ġ-> ĠAA ): ĠValid ated < EE , ĠAA > Ġ= Ġfold ({ ĠInvalid ( fe ( it )) Ġ}, Ġ{ ĠValid ( fa ( it )) Ġ}) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠApply Ġa Ġfunction Ġto Ġa ĠValid Ġvalue , Ġreturning Ġa Ġnew ĠValid Ġvalue ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< B > Ġmap ( f : Ġ( A ) Ġ-> ĠB ): ĠValid ated < E , ĠB > Ġ= Ġb imap (:: identity ) Ġ{ Ġf ( it ) Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠApply Ġa Ġfunction Ġto Ġan ĠInvalid Ġvalue , Ġreturning Ġa Ġnew ĠInvalid Ġvalue . ĊĠĠ Ġ* ĠOr , Ġif Ġthe Ġoriginal Ġvalid Ġwas ĠValid , Ġreturn Ġit . ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< EE > Ġleft Map ( f : Ġ( E ) Ġ-> ĠEE ): ĠValid ated < EE , ĠA > Ġ= Ġb imap ({ Ġf ( it ) Ġ}, Ġ:: identity ) ĊĊĠ Ġ/** ĊĠĠ Ġ* Ġapply Ġthe Ġgiven Ġfunction Ġto Ġthe Ġvalue Ġwith Ġthe Ġgiven ĠB Ġwhen ĊĠĠ Ġ* Ġvalid , Ġotherwise Ġreturn Ġthe Ġgiven ĠB ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< B > Ġfold Left ( b : ĠB , Ġf : Ġ( B , ĠA ) Ġ-> ĠB ): ĠB Ġ= Ġfold ({ Ġb Ġ}, Ġ{ Ġf ( b , Ġit ) Ġ}) ĊĊĠ Ġfun Ġ< B > Ġfold Right ( lb : ĠEval < B >, Ġf : Ġ( A , ĠEval < B >) Ġ-> ĠEval < B >): ĠEval < B > Ġ= ĊĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠ Ġis ĠValid Ġ-> Ġf ( this . a , Ġlb ) ĊĠĠĠĠĠ Ġis ĠInvalid Ġ-> Ġlb ĊĠĠĠ Ġ} ĊĊĠ Ġfun Ġswap (): ĠValid ated < A , ĠE > Ġ= Ġfold ({ ĠValid ( it ) Ġ}, Ġ{ ĠInvalid ( it ) Ġ}) Ċ } Ċ Ċ /** Ċ Ġ* ĠReturn Ġthe ĠValid Ġvalue , Ġor Ġthe Ġdefault Ġif ĠInvalid Ċ Ġ*/ Ċ fun Ġ< E , ĠB > ĠValid ated Of < E , ĠB >. getOrElse ( default : Ġ() Ġ-> ĠB ): ĠB Ġ= ĊĠ Ġfix (). fold ({ Ġdefault () Ġ}, Ġ:: identity ) Ċ Ċ /** Ċ Ġ* ĠReturn Ġthe ĠValid Ġvalue , Ġor Ġnull Ġif ĠInvalid Ċ Ġ*/ Ċ fun Ġ< E , ĠB > ĠValid ated Of < E , ĠB >. or Null (): ĠB ? Ġ= ĊĠ Ġget OrElse Ġ{ Ġnull Ġ} Ċ Ċ /** Ċ Ġ* ĠReturn Ġthe ĠValid Ġvalue , Ġor Ġthe Ġresult Ġof Ġf Ġif ĠInvalid Ċ Ġ*/ Ċ fun Ġ< E , ĠB > ĠValid ated Of < E , ĠB >. value Or ( f : Ġ( E ) Ġ-> ĠB ): ĠB Ġ= ĊĠ Ġfix (). fold ({ Ġf ( it ) Ġ}, Ġ:: identity ) Ċ Ċ /** Ċ Ġ* ĠIf Ġ` this ` Ġis Ġvalid Ġreturn Ġ` this `, Ġotherwise Ġif Ġ` that ` Ġis Ġvalid Ġreturn Ġ` that `, Ġotherwise Ġcombine Ġthe Ġfailures . Ċ Ġ* ĠThis Ġis Ġsimilar Ġto Ġ[ orElse ] Ġexcept Ġthat Ġhere Ġfailures Ġare Ġaccumulated . Ċ Ġ*/ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. find Valid ( SE : ĠSem ig roup < E >, Ġthat : Ġ() Ġ-> ĠValid ated < E , ĠA >): ĠValid ated < E , ĠA > Ġ= ĊĠ Ġfix (). fold ( ĊĊĠĠĠ Ġ{ Ġe Ġ-> ĊĠĠĠĠĠ Ġthat (). fold ( ĊĠĠĠĠĠĠĠ Ġ{ Ġee Ġ-> ĠInvalid ( SE . run Ġ{ Ġe . combine ( ee ) Ġ}) Ġ}, ĊĠĠĠĠĠĠĠ Ġ{ ĠValid ( it ) Ġ} ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ}, ĊĠĠĠ Ġ{ ĠValid ( it ) Ġ} ĊĠ Ġ) Ċ Ċ /** Ċ Ġ* ĠReturn Ġthis Ġif Ġit Ġis ĠValid , Ġor Ġelse Ġfall Ġback Ġto Ġthe Ġgiven Ġdefault . Ċ Ġ* ĠThe Ġfunctionality Ġis Ġsimilar Ġto Ġthat Ġof Ġ[ find Valid ] Ġexcept Ġfor Ġfailure Ġaccum ulation , Ċ Ġ* Ġwhere Ġhere Ġonly Ġthe Ġerror Ġon Ġthe Ġright Ġis Ġpreserved Ġand Ġthe Ġerror Ġon Ġthe Ġleft Ġis Ġignored . Ċ Ġ*/ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. orElse ( default : Ġ() Ġ-> ĠValid ated < E , ĠA >): ĠValid ated < E , ĠA > Ġ= ĊĠ Ġfix (). fold ( ĊĠĠĠ Ġ{ Ġdefault () Ġ}, ĊĠĠĠ Ġ{ ĠValid ( it ) Ġ} ĊĠ Ġ) Ċ Ċ /** Ċ Ġ* ĠFrom ĠApply : Ċ Ġ* Ġif Ġboth Ġthe Ġfunction Ġand Ġthis Ġvalue Ġare ĠValid , Ġapply Ġthe Ġfunction Ċ Ġ*/ Ċ fun Ġ< E , ĠA , ĠB > ĠValid ated Of < E , ĠA >. ap ( SE : ĠSem ig roup < E >, Ġf : ĠValid ated < E , Ġ( A ) Ġ-> ĠB >): ĠValid ated < E , ĠB > Ġ= ĊĠ Ġfix (). fold ( ĊĠĠĠ Ġ{ Ġe Ġ-> Ġf . fold ({ ĠInvalid ( SE . run Ġ{ Ġit . combine ( e ) Ġ}) Ġ}, Ġ{ ĠInvalid ( e ) Ġ}) Ġ}, ĊĠĠĠ Ġ{ Ġa Ġ-> Ġf . fold (:: Invalid ) Ġ{ ĠValid ( it ( a )) Ġ} Ġ} ĊĠ Ġ) Ċ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. handle Left With ( f : Ġ( E ) Ġ-> ĠValid ated Of < E , ĠA >): ĠValid ated < E , ĠA > Ġ= ĊĠ Ġfix (). fold ({ Ġf ( it ). fix () Ġ}, Ġ:: Valid ) Ċ Ċ fun Ġ< G , ĠE , ĠA , ĠB > ĠValid ated Of < E , ĠA >. traverse ( GA : ĠApplic ative < G >, Ġf : Ġ( A ) Ġ-> ĠKind < G , ĠB >): ĠKind < G , ĠValid ated < E , ĠB >> Ġ= ĠGA . run Ġ{ ĊĠ Ġfix (). fold ({ Ġe Ġ-> Ġjust ( Invalid ( e )) Ġ}, Ġ{ Ġa Ġ-> Ġf ( a ). map (:: Valid ) Ġ}) Ċ } Ċ Ċ fun Ġ< G , ĠE , ĠA > ĠValid ated Of < E , ĠKind < G , ĠA >> . sequence ( GA : ĠApplic ative < G >): ĠKind < G , ĠValid ated < E , ĠA >> Ġ= ĊĠ Ġfix (). traverse ( GA , Ġ:: identity ) Ċ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. combine ( ĊĠ ĠSE : ĠSem ig roup < E >, ĊĠ ĠSA : ĠSem ig roup < A >, ĊĠ Ġy : ĠValid ated Of < E , ĠA > Ċ ): ĠValid ated < E , ĠA > Ġ= ĊĠ Ġy . fix (). let Ġ{ Ġthat Ġ-> ĊĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠ Ġthis Ġis ĠValid Ġ&& Ġthat Ġis ĠValid Ġ-> ĠValid ( SA . run Ġ{ Ġa . combine ( that . a ) Ġ}) ĊĠĠĠĠĠ Ġthis Ġis ĠInvalid Ġ&& Ġthat Ġis ĠInvalid Ġ-> ĠInvalid ( SE . run Ġ{ Ġe . combine ( that . e ) Ġ}) ĊĠĠĠĠĠ Ġthis Ġis ĠInvalid Ġ-> Ġthis ĊĠĠĠĠĠ Ġelse Ġ-> Ġthat ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. combine K ( SE : ĠSem ig roup < E >, Ġy : ĠValid ated Of < E , ĠA >): ĠValid ated < E , ĠA > Ġ{ ĊĠ Ġval Ġx ev Ġ= Ġfix () ĊĠ Ġval Ġy ev Ġ= Ġy . fix () ĊĠ Ġreturn Ġwhen Ġ( xe v ) Ġ{ ĊĠĠĠ Ġis ĠValid Ġ-> Ġx ev ĊĠĠĠ Ġis ĠInvalid Ġ-> Ġwhen Ġ( y ev ) Ġ{ ĊĠĠĠĠĠ Ġis ĠInvalid Ġ-> ĠInvalid ( SE . run Ġ{ Ġx ev . e . combine ( y ev . e ) Ġ}) ĊĠĠĠĠĠ Ġis ĠValid Ġ-> Ġy ev ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠConverts Ġthe Ġvalue Ġto Ġan ĠI or < E , ĠA > Ċ Ġ*/ Ċ fun Ġ< E , ĠA > ĠValid ated Of < E , ĠA >. to I or (): ĠI or < E , ĠA > Ġ= ĊĠ Ġfix (). fold ({ ĠI or . Left ( it ) Ġ}, Ġ{ ĠI or . Right ( it ) Ġ}) Ċ Ċ fun Ġ< A > ĠA . valid (): ĠValid ated < Nothing , ĠA > Ġ= ĊĠ ĠValid ( this ) Ċ Ċ fun Ġ< E > ĠE . invalid (): ĠValid ated < E , ĠNothing > Ġ= ĊĠ ĠInvalid ( this ) Ċ Ċ fun Ġ< A > ĠA . valid N el (): ĠValid ated N el < Nothing , ĠA > Ġ= ĊĠ ĠValid ated . valid N el ( this ) Ċ Ċ fun Ġ< E > ĠE . invalid N el (): ĠValid ated N el < E , ĠNothing > Ġ= ĊĠ ĠValid ated . invalid N el ( this ) Ċ