2012-01-30 31 views
13

मैंने सोचा PartialFunctionMonoid हो सकता है। क्या मेरा विचार प्रक्रिया सही है? उदाहरण के लिए,स्कैला आंशिक समारोह Monoid हो सकता है?

import scalaz._ 
import scala.{PartialFunction => -->} 

implicit def partialFunctionSemigroup[A,B]:Semigroup[A-->B] = new Semigroup[A-->B]{ 
    def append(s1: A-->B, s2: => A-->B): A-->B = s1.orElse(s2) 
} 

implicit def partialFunctionZero[A,B]:Zero[A-->B] = new Zero[A-->B]{ 
    val zero = new (A-->B){ 
    def isDefinedAt(a:A) = false 
    def apply(a:A) = sys.error("error") 
    } 
} 

लेकिन वर्तमान संस्करण Scalaz (6.0.4) यह शामिल नहीं है। क्या इसमें कुछ शामिल नहीं है?

+0

मुझे लगता है आप जानते हैं कि 'Function1' रचना के तहत एक monoid है कर रहे हैं? –

+1

@ डीसीएसओब्राल 'फंक्शन 1 [ए, ए]', उर्फ ​​'एंडो [ए]', है। – retronym

उत्तर

28

चलिए इस पर एक अलग प्रकाश चमकते हैं।

PartialFunction[A, B]A => Option[B] isomorphic को है। (वास्तव में, जाँच करने में सक्षम अगर यह B के मूल्यांकन को ट्रिगर के बिना उसकी A के लिए परिभाषित किया गया है हो सकता है, आप A => LazyOption[B] की आवश्यकता होगी)

हम एक Monoid[A => Option[B]] हम अपने दावे को साबित कर दिया गया है पा सकते हैं तो अगर।

को देखते हुए Monoid[Z], इस प्रकार हम Monoid[A => Z] फार्म कर सकते हैं:

implicit def readerMonoid[Z: Monoid] = new Monoid[A => Z] { 
    def zero = (a: A) => Monoid[Z].zero 
    def append(f1: A => Z, f2: => A => Z) = (a: A) => Monoid[Z].append(f1(a), f2(a)) 
} 

तो, क्या monoid (रों) अगर हम हमारे Z रूप Option[B] का उपयोग हम क्या ज़रूरत है? स्कालाज तीन प्रदान करता है। प्राथमिक उदाहरण के लिए Semigroup[B] की आवश्यकता होती है।

implicit def optionMonoid[B: Semigroup] = new Monoid[Option[B]] { 
    def zero = None 
    def append(o1: Option[B], o2: => Option[B]) = o1 match { 
    case Some(b1) => o2 match { 
     case Some(b2) => Some(Semigroup[B].append(b1, b2))) 
     case None => Some(b1) 
    case None => o2 match { 
     case Some(b2) => Some(b2) 
     case None => None 
    } 
    } 
} 

इस का उपयोग करते हुए:

scala> Monoid[Option[Int]].append(Some(1), Some(2)) 
res9: Option[Int] = Some(3) 

लेकिन वह दो विकल्प गठबंधन करने के लिए एक ही रास्ता नहीं है। मामले में दो विकल्पों की सामग्री को जोड़ने के बजाय वे Some दोनों हैं, हम केवल पहले या अंतिम दोनों को चुन सकते हैं। दो इसे ट्रिगर करते हैं, हम टैग किए गए प्रकार नामक चाल के साथ एक अलग प्रकार बनाते हैं। यह हास्केल के newtype पर आत्मा में समान है।

scala> import Tags._ 
import Tags._ 

scala> Monoid[Option[Int] @@ First].append(Tag(Some(1)), Tag(Some(2))) 
res10: [email protected]@[Option[Int],scalaz.Tags.First] = Some(1) 

scala> Monoid[Option[Int] @@ Last].append(Tag(Some(1)), Tag(Some(2))) 
res11: [email protected]@[Option[Int],scalaz.Tags.Last] = Some(2) 

Option[A] @@ First, संलग्न के माध्यम से यह Monoid है, अपने उदाहरण के रूप में ही orElse अर्थ विज्ञान का उपयोग करता है।

तो, यह सब एक साथ डाल:

scala> Monoid[A => Option[B] @@ First] 
res12: scalaz.Monoid[A => [email protected]@[Option[B],scalaz.Tags.First]] = 
     [email protected] 
+0

बहुत बहुत धन्यवाद! मुझे एहसास नहीं हुआ था कि आंशिक कार्य ए => LazyOption [बी] –

+0

के लिए isomorphic है धन्यवाद, @ पीछे उच्चारण! टैग किए गए प्रकार केवल स्केलज़-सात में उपलब्ध हैं, पिछले संस्करण के लिए फर्स्टऑप्शन विशेषता का उपयोग करना आवश्यक है, क्या मैं सही हूँ? – lester

+2

@lester हाँ, बिल्कुल। टैग किए गए प्रकारों में कुछ तेज किनारों हैं, दुर्भाग्यवश, हम उन्हें अनुशंसा करने से पहले बेहतर स्केलैक समर्थन की आवश्यकता हो सकती है। उदाहरण है: 'सूची (टैग (1))' कंप्रेसर के एक हिस्से के रूप में 'क्लासकास्टएक्सप्शन' देता है, तर्क को ऑब्जेक्ट सरणी के रूप में और बाद में भाग को आदिम सरणी के रूप में मानता है। – retronym

2

नहीं, यह अच्छा लग रहा है, दोनों के लिए (गैर विनिमेय) monoid आवश्यकताओं को संतोषजनक। दिलचस्प विचार आप किस मामले का समर्थन करने की कोशिश कर रहे हैं?

+0

क्षमा करें, लेकिन पहचान स्पष्ट रूप से उल्लंघन किया गया है। –

+1

@Heiko क्षमा करें, लेकिन आपका कथन स्पष्ट रूप से गलत है। भले ही जवाब गलत है, यह स्पष्ट से दूर है (कम से कम मेरे लिए)। – ziggystar

0

आपका शून्य निश्चित रूप से पहचान तत्व के लिए स्वयंसिद्ध का उल्लंघन करती है, लेकिन मुझे लगता है कि पहचान (आंशिक) समारोह ठीक हो जाएगा।

आपका संलग्न भी monoid कानूनों को पूरा नहीं करता है, लेकिन इसके बजाय की orElse आप andthen (रचना) कह सकते हैं। लेकिन यह केवल ए == बी:

implicit def partialFunctionSemigroup[A]: Semigroup[A --> A] = new Semigroup[A --> A] { 
    def append(s1: A --> A, s2: => A --> A): A-->A = s1 andThen s2 
} 

implicit def partialFunctionZero[A]: Zero[A --> A] = new Zero[A --> A] { 
    val zero = new (A --> A) { 
    def isDefinedAt(a:A) = true 
    def apply(a:A) = a 
    } 
} 
+0

क्या आप काउंटर-उदाहरण दे सकते हैं? – ziggystar

+0

पहचान कानून: ea = a = ae –

+0

किस 'ई' और' ए 'का उल्लंघन किया जाता है? – ziggystar