2011-10-04 8 views
11

मैं राज्य मोनैड में मूल्य लगाने के लिए स्कालज़ की pure विधि को कॉल करना चाहता हूं। निम्नलिखित काम करता है:स्कैला में, क्या सामान्य प्रकार की धैर्य को कम करने के लिए एक शॉर्टेंड है?

type IntState[A] = State[Int, A] 
val a = "a".pure[IntState] 
a(1) 
    (Int, java.lang.String) = (1,a) 

मैं भी प्रकार उर्फ ​​समाप्त कर सकते हैं (धन्यवाद Scalaz के Pure.scala):

val a = "a".pure[({type T[A]=State[Int,A]})#T] 
a(1) 
    (Int, java.lang.String) = (1,a) 

लेकिन वह बेहद भद्दा है। क्या इस तरह के एक प्रकार को संश्लेषित करने का एक छोटा रास्ता है? समारोह शाब्दिक के लिए प्लेसहोल्डर वाक्य रचना की तरह, वहाँ की तरह कुछ है:

"a".pure[State[Int, *]] 
+0

मुझे नहीं लगता कि स्कैला में ऐसी वाक्य रचनात्मक चीनी है, क्योंकि [मिचिड आंशिक प्रकार का आवेदन उद्धृत करता है] (http://stackoverflow.com/questions/7045967/what-are-type-projections-useful-for/7046860#7046860) प्रकार के अनुमानों की उपयोगिता के उदाहरण के रूप में। –

उत्तर

6

संक्षिप्त आंशिक प्रकार आवेदन (arity -2) स्काला में के लिए, आप निम्नलिखित के रूप में प्रकार अंकन इन्फ़िक्स कर सकते हैं।

type ![F[_, _], X] = TF { type ![Y] = F[X, Y] } 

"a".pure[(State!Int)# !] 

ध्यान दें कि हम दो arity प्रकार कन्स्ट्रक्टर (या उपनाम टाइप) के लिए संकेत को infix कर सकते हैं।

+0

मैं दूसरे '!' '' '' का नाम बदलूंगा, इसलिए मैं '(राज्य! Int) #?' लिख सकता हूं। –

+5

गैर-ऑपरेटर नाम टाइप सदस्य के लिए बेहतर होगा ताकि आप प्रकार प्रक्षेपण के बाद स्पेस को छोड़ सकें, यानी: 'विशेषता! [एफ [_, _], ए] {टाइप एक्स [बी] = एफ [ए, बी ]}; foo [(राज्य! इंट) #x] '। ऐसा मत सोचो कि इससे उससे अधिक कॉम्पैक्ट मिल सकता है। –

6

सुनिश्चित नहीं हैं कि अगर यह बेहतर रूप में उत्तीर्ण, लेकिन यहाँ एक दृष्टिकोण है कि दूसरे दिन ट्वीट किया @kmizu है:

scala> trait TF { 
    | type Apply[A] 
    | } 
defined trait TF 

scala> type Curried2[F[_, _]] = TF { 
    | type Apply[X] = TF { 
    |  type Apply[Y] = F[X, Y] 
    | } 
    | } 
defined type alias Curried2 

scala> "a".pure[Curried2[State]#Apply[Int]#Apply] 
res7: scalaz.State[Int,java.lang.String] = [email protected] 

आप कर सकते हैं यह प्रतीकात्मक प्रकार उपनामों का उपयोग करके थोड़ा अच्छा दिखता है।

scala> type ![F[_, _]] = TF { 
    | type ![X] = TF { 
    |  type ![Y] = F[X, Y] 
    | } 
    | } 
defined type alias $bang 

scala> "a".pure[![State]# ![Int]# !] 
res9: scalaz.State[Int,java.lang.String] = [email protected] 
+0

क्या होता है जब आप पहले प्रकार पैरामीटर को बांधना चाहते हैं? मुझे लगता है कि आपको Curried2 के दूसरे संस्करण की आवश्यकता है? – IttayD

+1

@IttayD: उसे करीकरण नहीं कहा जाएगा, और आप उस मामले में प्रकार लैम्ब्डा वाक्यविन्यास का उपयोग करना बेहतर होगा। (हास्केल के करीबी प्रकार कन्स्ट्रक्टर सिंटैक्स पर प्रकार लैम्ब्डा सिंटैक्स के इस छोटे से लाभ को कुछ मेलिंग सूची में टोनी मॉरिस द्वारा भी नोट किया गया था।) इस जवाब में मैंने जो वाक्यविन्यास सुझाया है वह हास्केल शैली आंशिक प्रकार के अनुप्रयोग को अनुकरण करने के लिए है। '! [राज्य] #!' हास्केल में 'राज्य' के बराबर है, '! [राज्य] #! [Int] #!' 'राज्य Int' आदि। – missingfaktor

+0

@ डाउनवॉटर: आपके डाउनवोट को समझाने की देखभाल? – missingfaktor

1

धर्मार्थ को कम करने का सबसे लोकप्रिय तरीका दयालु प्रोजेक्टर (https://github.com/non/kind-projector) प्लगइन है जिसका उपयोग बिल्लियों पुस्तकालय में भी किया जाता है।

val a = "a".pure[State[Int, ?]] 

नोट:: द्वारा यह आपके उदाहरण प्लगइन को सक्रिय करने के लिए परिवर्तित किया जा सकता इस वाक्य डिफ़ॉल्ट रूप से Dotty में सक्षम हो जाएगा।