2010-07-28 13 views
6

मैं चारों ओर ListW.<^> साथ खेल रहा था, परिभाषा जिनमें से इस प्रकार है:Scalaz.ListW का उपयोग करके अनुमान प्रश्न टाइप करें। <^>

def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match { 
    case Nil => ∅ 
    case h :: t => f(Scalaz.nel(h, t)) 
} 

मैं समझ नहीं कैसे आ Option इस उदाहरण

scala> case class CC(v : Int) 
defined class CC 

scala> val posns = List(CC(2), CC(5), CC(1)) 
posns: List[CC] = List(CC(2), CC(5), CC(1)) 

तो के लिए Zero प्रकार के रूप में चुना जा रहा है अब मेरे पास इन चीजों की एक सूची है। मेरा लक्ष्य Option[CC] को posns के न्यूनतम/अधिकतम के लिए वापस प्राप्त करना है, जहां शून्य के नीचे कोई मान नहीं है और अधिकतम के लिए समान नहीं है, तो मुझे न्यूनतम के लिए None मिलता है।

scala> import scalaz._; import Scalaz._ 
import scalaz._ 
import Scalaz._ 

scala> implicit val CCOrder = new Order[CC] { 
     | def order(v1 : CC, v2 : CC) = orderBy((v : CC) => v.v).order(v1, v2) 
     | } 
CCOrder: java.lang.Object with scalaz.Order[CC] = [email protected] 

scala> posns.filter(_.v < 0) <^> (_.min) 
res0: Option[CC] = None 

scala> posns.filter(_.v > 0) <^> (_.max) 
res1: Option[CC] = Some(CC(5)) 

विकल्प बिल्कुलZero प्रकार मैं चाहता था! क्या कोई समझा सकता है कि Option को टाइपर द्वारा कैसे चुना जा रहा है? मैं इसे घोषित नहीं करता!

उत्तर

5

ListW#<^> और MA#min के लिए परिभाषाएँ:

sealed trait MA[M[_], A] extends PimpedType[M[A]] { 
    def min(implicit r: Foldable[M], ord: Order[A]): Option[A] = 
    foldl1((x: A, y: A) => if (x ≨ y) x else y) 
} 

sealed trait ListW[A] extends PimpedType[List[A]] { 
    def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match { 
    case Nil => ∅ 
    case h :: t => f(Scalaz.nel(h, t)) 
    } 
} 

यहाँ प्रासंगिक अनुमानित प्रकार, अंतर्निहित रूपांतरण, और अंतर्निहित मापदंड हैं। scalac -Xprint:typer इसे प्रकट करेगा।

object test { 
    import scalaz._ 
    import Scalaz._ 

    case class CC(v: Int) 
    val posns = List(CC(2), CC(5), CC(1)) 
    val filtered = posns.filter(((x$1: CC) => x$1.v.<(0))) 
    val listw = Scalaz.ListTo[CC](posns.filter(((x$1: CC) => x$1.v.<(0)))) 
    listw.<^>[Option[CC]]{ 
    (x$2: scalaz.NonEmptyList[CC]) => 
     Scalaz.maImplicit[scalaz.NonEmptyList, CC](x$2).min(Foldable.NonEmptyListFoldable, CCOrder) 
    }(Zero.OptionZero[CC]); 
} 

[email protected]#<^> अन्यथा प्रकार B के लिए Zero देता है, NonEmptyList[A] => B से प्रदान समारोह चलाता है अगर pimped सूची गैर खाली है। MA#min वास्तव में Option[B] देता है - यह कंटेनरों के लिए एक सामान्य कार्य है, NonEmptyList के लिए विशिष्ट नहीं, जहां यह B लौटा सकता है।

इसे प्राप्त करने का एक और सीधा तरीका MA#min पर सीधे कॉल करना है। दुर्भाग्य से, List पहले से ही एक min समारोह, स्काला 2.8 में नया है, इसलिए MA लिए अंतर्निहित दृश्य एक प्रकार संकेत के बिना ट्रिगर नहीं है:

posns.filter(_.v < 0).min 
<console>:16: error: could not find implicit value for parameter cmp: Ordering[CC] 
    posns.filter(_.v < 0).min 

(posns.filter(_.v < 0): MA[List, CC]).min 
res7: Option[CC] = None 

यह प्रेरित कारणों Scalaz में प्रतीकात्मक पहचानकर्ता प्रदान करने के लिए में से एक है - यह नामस्थान का एक कच्चा रूप है!

साइड नोट: यदि आप CC के लिए Order उदाहरण के अपने उदाहरण को आसान बनाने में कर सकते हैं:

implicit val CCOrder: Order[CC] = orderBy(_.v) 
CCOrder: scalaz.Order[CC] = [email protected] 
+0

शुरू में, आप 'एमए # min' के बजाय' एमए # max' की परिभाषा देते हैं। –

+0

आह। तो मेरा अगला प्रश्न होगा - "' एमए 'क्यों' एमए 'से आ रहा है और' पहचान 'नहीं है? " –

+0

@alexey: अपडेट किया गया। 'x.min (y)' 'पहचान ',' xs.min' मैचों' एमए 'से आता है। – retronym

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