2011-10-03 12 views
5

के रूप में देखा यह एक या that one की तरह एक हस्ताक्षर को देखते हुए:स्ट्रिंग एक monoid

def foo[A, F[_]](implicit mon: Monoid[F[A]], pr: Pure[F]): F[A] 

मान लिया जाये कि एक Char है, वहाँ एक रास्ता एक List[Char] के बजाय एक String प्राप्त करने के लिए है?

String एक प्रकार पैरामीटर नहीं लेता है, इसलिए मुझे लगता है कि यह संभव नहीं है। अगला सबसे अच्छा विकल्प क्या है? अभी, मैं परिणाम पर mkString का उपयोग करता हूं, लेकिन यह इष्टतम महसूस नहीं करता है।

मुझे लगता है कि Stringशून्य"" और साथ एक monoid संलग्न है+ ...

+0

आपको केवल मोनॉयड [एफ] के बजाय मोनॉयड [एफ [ए]] की आवश्यकता क्यों है? – CheatEx

+0

@CheatEx, इस मामले में, मैं वह नहीं हूं जिसने 'foo' लिखा था, मैं सिर्फ कॉलर हूं। – huynhjl

उत्तर

7

स्ट्रिंग को उच्च-प्रकार के प्रकार के रूप में मास्करेड करने के लिए राजी करना संभव है, और इसलिए लागू होने के लिए foo के रूपों के कार्यों की अनुमति दें। हालांकि, स्काला के प्रकार निष्कर्ष foo के प्रकार तर्क का निष्कर्ष निकालते का काम करने के लिए वर्तमान में नहीं है, तो आप उन्हें स्पष्ट रूप से आपूर्ति करने के लिए

// Assuming the the definitions of Pure and Monoid from Scalaz 

type ConstString = { 
    type λ[X] = String 
} 

implicit def StringPure = new Pure[ConstString#λ] { 
    def pure[A](a: => A) = a.toString 
} 

val sm = implicitly[Monoid[String]] 
val sp = implicitly[Pure[ConstString#λ]] 
val f : String = foo[Char, ConstString#λ](sm, sp) // OK 

ध्यान दें कि foo को Char प्रकार तर्क अप्रयुक्त है और कर सकते हैं करेंगे कुछ भी हो, लेकिन कुछ होना चाहिए: इस मामले में या तो Char प्राकृतिक विकल्प है, लेकिन Nothing या Any भी होगा।

ध्यान दें कि String के विशेष विशेषताओं पर इस समाधान ट्रेडों: सभी प्रकार के मूल्यों String के लिए परिवर्तनीय हैं इसलिए pure[A](a : => A) : String सभी प्रकार A के लिए कार्यान्वयन योग्य है रहा है। String के अलावा अन्य प्रकार के लिए इस मुहावरे को दोहराने के लिए pure (उदाहरण के लिए किसी प्रकार का पैटर्न मिलान) के प्रकार में विशिष्ट-विशिष्ट मामलों को लागू करने के लिए कुछ तंत्र का उपयोग करना होगा।

+2

लेकिन 'निहित [शुद्ध [कॉन्स्टस्ट्रिंग # λ]] शुद्ध (' ए ')' खाली स्ट्रिंग वापस कर देगा, इसलिए यह वास्तव में बहुत अधिक उपयोग नहीं है। क्या यह? –

+0

निश्चित रूप से, आपको किसी भी उपयोगी काम के लिए 'शुद्ध [ConstString # λ]' की एक अलग परिभाषा की आवश्यकता होगी। इसका जवाब देने के लिए संपादित उत्तर। –

+0

मुझे लगता है कि मैंने एक केस्ट्रल देखा! –

0

आपका विश्लेषण, कि स्केला के प्रकार प्रणाली एक "उच्च kinded प्रकार" नहीं होने के रूप में स्ट्रिंग को अस्वीकार कर देंगे * -> * सही है। यही कारण है,

def foo[A, F[_], That](implicit mon: Monoid[F[A]], pr: Pure[F], FA_Is_That: F[A] <%< That) 

है प्रकार स्ट्रिंग नहीं (मैं इस जांच न की हो) अंतर्निहित रूपांतरण किसी भी एफ आप की कोशिश कर सकते के लिए F[_] को आबंटित है ... ... लेकिन यह है कि उपयोगी मैं नहीं होगा संदिग्ध क्योंकि आपको अपने स्वयं के bespoke रूपांतरण प्रदान करना होगा जहां आवश्यक हो लेकिन प्रदर्शन भी भयानक होगा, यह मानते हुए कि यह कोड का एक गर्म हिस्सा है।

या, मानक पुस्तकालय का उपयोग कर, आप CanBuildFrom मशीनरी इस्तेमाल कर सकते हैं लेकिन यह स्पष्ट कतई नहीं है कि कैसे अच्छी तरह से इस scalaz शैली typeclasses साथ मिश्रण होगा।

def foo[A, F[_], That](implicit mon: Monoid[F[A]], pr: Pure[F], b: CanBuildFrom[A, F[A], That]): That 

विधि के शरीर में, जाहिर है, आप वापसी मान के निर्माण के लिए निर्माता का उपयोग करना, के रूप में monoid/शुद्ध typeclasses करने का विरोध किया है, उन्हें कुछ हद तक निरर्थक प्रतिपादन की आवश्यकता होगी, मुझे लगता है।

6

सबसे अच्छा समाधान मैं इसके बारे में सोच सकता हूं List[Char] से String पर एक अंतर्निहित रूपांतरण को परिभाषित करना है।