6

मैंक्या मैं इस रचना को सरल बनाने के लिए मोनाड ट्रांसफार्मर का उपयोग कर सकता हूं?

type VS[A] = Validation[String, A] 

val v: VS[Option[A]] 
val f: A => VS[B] 

है लगता है मुझे प्रकार VS[Option[B]] का एक परिणाम प्राप्त करना चाहते हैं, लेकिन अगर v एक Success(None) है, परिणाम भी एक Success(None) होना चाहिए।

scala> val v: VS[Option[String]] = some("4.5").success 
v: VS[Option[String]] = Success(Some(4.5)) 

scala> val f = (s : String) => (try { s.toInt.success } catch { case x => x.getMessage.fail }): VS[Int] 
f: String => VS[Int] = <function1> 

तब:

scala> import Validation.Monad._ 
import Validation.Monad._ 

scala> (v map2 f map (_.sequence)).join 
res4: scalaz.Validation[String,Option[Int]] = Failure(For input string: "4.5") 

सफलता मामला है:

scala> val v: VS[Option[String]]= some("5").success 
v: VS[Option[String]] = Success(Some(5)) 

scala> (v map2 f map (_.sequence)).join //UGLY composition 
res7: scalaz.Validation[String,Option[Int]] = Success(Some(5)) 

और खाली मामला है:

scala> val v: VS[Option[String]]= none[String].success 
v: VS[Option[String]] = Success(None) 

scala> (v map2 f map (_.sequence)).join 
res6: scalaz.Validation[String,Option[Int]] = Success(None) 

एक "अच्छे है यहाँ एक उदाहरण है "ऐसा करने का तरीका (संभवतः क्लेस्ली संरचना या एम शामिल है ओनड ट्रांसफार्मर)?

उत्तर

5

मोनैड ट्रांसफार्मर OptionT वही करता है जो आप यहां चाहते हैं, और इसकी flatMapF विधि उपयोग को एक क्लीनर-लाइनर बनाती है।

मैं इस उदाहरण में Validation के बजाय स्कालाज़ 7 के संयोजन प्रकार (\/) का उपयोग करने जा रहा हूं, क्योंकि बाद वाला स्केलज़ 7 में एक मोनड नहीं है, लेकिन सिद्धांत समान है।

import scalaz._, std.option._, syntax.id._, syntax.monad._ 

type DS[+A] = String \/ A 
type ODS[A] = OptionT[DS, A] 

def f(s: String) = try s.toInt.right catch { case e => e.getMessage.left } 

अब हम लिख सकते हैं निम्नलिखित:

scala> val v = OptionT(some("4.5").point[DS]) 
v: scalaz.OptionT[DS,java.lang.String] = OptionT(\/-(Some(4.5))) 

scala> (v flatMapF f).run 
res0: DS[Option[Int]] = -\/(For input string: "4.5") 

या समतुल्य:

scala> ("4.5".point[ODS] flatMapF f).run 
res1: DS[Option[Int]] = -\/(For input string: "4.5") 

या सफलता मामला:

scala> ("4".point[ODS] flatMapF f).run 
res2: DS[Option[Int]] = \/-(Some(4)) 

या खाली मामला:

+०१२३५१६४१०६
scala> (OptionT(none.point[DS]) flatMapF f).run 
res3: DS[Option[Int]] = \/-(None) 

वांछित के रूप में।

संबंधित मुद्दे

 संबंधित मुद्दे