2012-11-25 54 views
5

जावा 6 में मोनड व्यक्त करने का सामान्य मामला है? "सामान्य मामला" शब्द नोट करें — यह संभव हो सकता है कि मोनड का सामान्य मामला स्पष्ट नहीं है, हालांकि मोनड के कई विशेष मामले (यानी कई विशिष्ट मोनैड) स्पष्ट हैं।जावा 6 में मोनड व्यक्त करने का सामान्य मामला है?

समस्या यहाँ (कमी) Higher-kinded generics in Java है; हालांकि, मैंने देखा कि नमूना हास्केल कोड वास्तव में https://stackoverflow.com/a/877036/1123502 (यानी public class Fix<F extends Fix<F>>) जैसे दृष्टिकोण का उपयोग कर जावा पर पोर्ट किया गया था।

बेशक

, गैर प्रकार सुरक्षित कार्यान्वयन (वस्तु और downcasts का उपयोग कर की तरह) दिलचस्प नहीं हैं।

अद्यतन: 2 आम मोनैड परिभाषाएं हैं: जुड़ें-एफएमएपी और बाइंड-रिटर्न। यद्यपि वे (गणितीय) समकक्ष हैं, लेकिन वे इस अर्थ में समकक्ष नहीं हो सकते हैं कि जावा में एक परिभाषा व्यक्त की जा सकती है, जबकि अन्य नहीं है (हालांकि, ऐसा लगता है कि गैर समकक्ष असंभव है)। तो मेरा सवाल दोनों परिभाषाओं की चिंता करता है।

लब्बोलुआब यह है: किसी को सभी बाधाओं को दूर किया और जावा 6 में लिखा था "सामान्य स्थिति" इकाई? या, वैकल्पिक रूप से, कृपया एक पेपर, या एक पूरी तरह से ब्लॉग पोस्ट इंगित करें, या पूरी तरह से समझाएं कि यह क्यों संभव नहीं है।

+2

यह भी देखें [* जावा * में मोनाड्स] (http://logicaltypes.blogspot.com/2011/09/monads-in-java.html)। – trashgod

+2

@trashgod नोट हालांकि उस कार्यान्वयन में 'बाइंड' का रिटर्न प्रकार 'मोनाड ' है -' एम 'नहीं, जो जावा में संभव नहीं होगा। नतीजतन यदि आपके पास मोनाड से प्राप्त एक लिस्ट क्लास है, तो इस बात की कोई गारंटी नहीं है कि ऐसी सूची में 'बाइंड' को कॉल करने से दूसरी सूची तैयार होगी, इसलिए 'मोनाडिकलिस्ट स्ट्रिंग्स = myMonadicList.bind जैसे कुछ लिखना कानूनी नहीं होगा (...) बिना किसी कलाकार के। ... – sepp2k

+1

... तो उस आलेख में दिया गया अमूर्त वर्ग मोनैड अवधारणा का पूरी तरह से सही कार्यान्वयन नहीं है (हालांकि यह संभव है कि आप जावा में जितना सही हो उतना सही हो)। – sepp2k

उत्तर

5

गंदी कास्टिंग चाल के बिना नहीं। जैसा कि आपने पहले ही उल्लेख किया है कि जावा स्तरीय भूमि में टाइप लेवल पॉलीमोर्फिज्म (ए.के.ए. "उच्च प्रकार के प्रकार" का समर्थन नहीं करता है)।

यहाँ एक तरीका है: आप एक functor लागू करने के लिए चाहते हैं। आप Functor<F<A>> लिखना चाहते हैं, जहां F उदा। एक List या Maybe, लेकिन यह काम नहीं करता है। लेकिन आपके पास उच्च श्रेणी वाली सामग्री के लिए "बेस क्लास" Base<X,Y> हो सकता है। X आपकी असली कक्षा के लिए List जैसे "गवाह" होना चाहिए। Y सामान्य जेनेरिक पैरामीटर है। अब आप अपने functor Functor<Base<F,A>> हो जाता है, लेकिन सभी वर्गों है कि इस के साथ इस्तेमाल किया जा करना चाहते हैं, Base<X,Y> लागू करने की आवश्यकता:

class List<A> implements Base<List.Witness,A> { 
    public class Witness{} 
    ... 
} 

public interface Functor<F> { 
    public <A, B> Base<F, B> map(F1<A, B> fn, Base<F, A> nestedA); 
} 

public class ListFunctor implements Functor<List.Witness> { 
    public <A, B> Base<List.Witness, B> map(F1<A, B> fn, Base<List.Witness, A> nestedA) { 
     ... 
    } 
} 

बेशक कीमत अदा करने को कि तुम वापस एक Base<List.Witness,B>, नहीं एक List<B> मिलता है। यह ठीक हो सकता है यदि आप उस उच्च-प्रकार वाले डोमेन में रहते हैं, और निश्चित रूप से आप सुविधा के लिए रूपांतरण कार्य कर सकते हैं, लेकिन यह अभी भी बहुत अच्छा नहीं है।

एक कार्यान्वयन के लिए मेरी नहीं-तो-गंभीर परियोजना highJ देखते हैं। ध्यान दें कि मैं ऊपर दिए गए उदाहरण के करीब एक पूरी तरह से पुनर्लेखित और थोड़ा अधिक सुविधाजनक संस्करण पर काम कर रहा हूं।

गंभीर कोड के लिए, बजाय स्काला में इस तरह के सामान लिखने पर विचार (या Scalaz उपयोग करें)।