स्काला में एक उच्च प्रकार का प्रकार क्या है?


275

आप वेब पर निम्नलिखित पा सकते हैं:

  1. उच्च प्रकार का टाइप == टाइप कंस्ट्रक्टर?

    class AClass[T]{...} // For example, class List[T]

    कुछ कहते हैं कि यह एक उच्च प्रकार का प्रकार है, क्योंकि यह उन प्रकारों पर अमूर्त है जो परिभाषा के अनुरूप होंगे।

    उच्च प्रकार के प्रकार वे प्रकार होते हैं जो अन्य प्रकार लेते हैं और एक नए प्रकार का निर्माण करते हैं

    हालांकि इन्हें टाइप कंस्ट्रक्टर के रूप में भी जाना जाता है । (उदाहरण के लिए, स्काला में प्रोग्रामिंग में )।

  2. उच्च प्रकार का टाइप == टाइप कंस्ट्रक्टर जो टाइप कंस्ट्रक्टर को एक प्रकार के पैरामीटर के रूप में लेता है?

    हायर काइंड के पेपर जेनरिक में आप पढ़ सकते हैं

    ... उस प्रकार के सार पर टाइप करने वाले सार ('उच्च-प्रकार के प्रकार') ... "

    जो सुझाव देता है

    class XClass[M[T]]{...} // or
    
    trait YTrait[N[_]]{...} // e.g. trait Functor[F[_]]

    एक उच्च प्रकार का प्रकार है।

तो इसे ध्यान में रखते हुए, टाइप कंस्ट्रक्टर , उच्च प्रकार के टाइप और टाइप कंस्ट्रक्टर के बीच अंतर करना मुश्किल है जो टाइप कंस्ट्रक्टर को टाइप पैरामीटर के रूप में लेता है , इसलिए ऊपर प्रश्न।


उदाहरण के तौर पर लांडे का फनकार जोड़ा गया।
लुट्ज़

जवाबों:


284

मुझे कुछ असमंजस के साथ पिच करके इस भ्रम को शुरू करने के लिए तैयार करना है। मैं इसे समझाने के लिए सादृश्य स्तर से मूल्य स्तर तक का उपयोग करना पसंद करता हूं, क्योंकि लोग इसके बारे में अधिक परिचित हैं।

एक प्रकार का कंस्ट्रक्टर एक प्रकार है जिसे आप टाइप करने के लिए तर्क टाइप करने के लिए आवेदन कर सकते हैं।

एक वैल्यू कंस्ट्रक्टर एक वैल्यू है जिसे आप वेल्यू "कंस्ट्रक्शन" करने के लिए वैल्यू आर्ग्यूमेंट्स पर अप्लाई कर सकते हैं।

मूल्य निर्माणकर्ताओं को आमतौर पर "फ़ंक्शन" या "तरीके" कहा जाता है। इन "कंस्ट्रक्टर्स" को "पॉलीमॉर्फिक" भी कहा जाता है (क्योंकि इनका उपयोग "अलग-अलग" आकार "के" सामान "के निर्माण के लिए किया जा सकता है), या" एब्स्ट्रक्शन "(क्योंकि वे अलग-अलग पॉलीमोर्फिक इंस्टीमेंट्स के बीच भिन्न होते हैं)।

अमूर्त / बहुरूपता के संदर्भ में, पहले-क्रम में अमूर्तता के "एकल उपयोग" को संदर्भित किया जाता है: आप एक बार एक प्रकार से अधिक सार करते हैं, लेकिन वह प्रकार स्वयं किसी भी चीज़ पर सार नहीं कर सकता है। जावा 5 जेनरिक फर्स्ट-ऑर्डर हैं।

अमूर्तता के उपरोक्त लक्षण वर्णन की पहली-क्रम व्याख्या है:

एक प्रकार का निर्माणकर्ता एक प्रकार है जिसे आप उचित प्रकार के "निर्माण" के लिए उचित प्रकार के तर्कों पर लागू कर सकते हैं।

एक वैल्यू कंस्ट्रक्टर एक ऐसा मूल्य है जिसे आप उचित मान के "कंस्ट्रक्शन" करने के लिए उचित मूल्य के तर्क पर लागू कर सकते हैं।

इस बात पर जोर देने के लिए कि इसमें कोई अमूर्तता शामिल नहीं है (मुझे लगता है कि आप इसे "शून्य-ऑर्डर" कह सकते हैं, लेकिन मैंने इसे कहीं भी उपयोग नहीं किया है), जैसे कि मूल्य 1या प्रकार String, हम आमतौर पर कहते हैं कि कुछ "उचित" मान या प्रकार है।

एक उचित मूल्य इस अर्थ में "तुरंत प्रयोग करने योग्य" है कि वह तर्कों का इंतजार नहीं कर रहा है (यह उनके ऊपर सार नहीं है)। उन्हें उन मूल्यों के रूप में सोचें जिन्हें आप आसानी से प्रिंट / निरीक्षण कर सकते हैं (एक फ़ंक्शन को धोखा देना धारावाहिक है!)।

एक उचित प्रकार एक प्रकार है जो मानों को वर्गीकृत करता है (वैल्यू कंस्ट्रक्टर सहित), टाइप कंस्ट्रक्टर किसी भी मान को वर्गीकृत नहीं करते हैं (उन्हें एक उचित प्रकार प्राप्त करने के लिए सही प्रकार के तर्कों पर लागू होने की आवश्यकता होती है)। एक प्रकार को तुरंत करने के लिए, यह आवश्यक है (लेकिन पर्याप्त नहीं) कि यह एक उचित प्रकार हो। (यह एक अमूर्त वर्ग या एक वर्ग हो सकता है, जिसकी आपके पास पहुँच नहीं है।)

"उच्च-क्रम" बस एक सामान्य शब्द है जिसका अर्थ है बार-बार बहुरूपता / अमूर्त का उपयोग। इसका अर्थ बहुरूपी प्रकारों और मूल्यों के लिए समान है। इसके विपरीत, एक उच्च-क्रम अमूर्त अमूर्त चीज पर कुछ सार करता है। प्रकारों के लिए, "उच्च-किन्नर" शब्द अधिक सामान्य "उच्च-क्रम" का एक विशेष-उद्देश्यीय संस्करण है।

इस प्रकार, हमारे लक्षण वर्णन का उच्च-क्रम संस्करण बन जाता है:

एक प्रकार का कंस्ट्रक्टर एक प्रकार है जिसे आप एक उचित प्रकार (कंस्ट्रक्टर) बनाने के लिए तर्क (उचित प्रकार या टाइप कंस्ट्रक्टर) पर लागू कर सकते हैं।

वैल्यू कंस्ट्रक्टर एक वैल्यू है जिसे आप वैल्यू आर्ग्यूमेंट (उचित मान या वैल्यू कंस्ट्रक्टर) पर लागू करके "वैल्यू" को एक उचित वैल्यू (कंस्ट्रक्टर) पर लागू कर सकते हैं।

इस प्रकार, "उच्च-क्रम" का सीधा मतलब यह है कि जब आप "एक्स पर अमूर्त" कहते हैं, तो आप वास्तव में इसका मतलब है! Xकर सकते हैं सार यह सब यह चाहता है: अधिक निकाला है कि है अपने स्वयं के "अमूर्त अधिकार" खोना नहीं करता। (वैसे, मैं यहां "अमूर्त" क्रिया का उपयोग करता हूं, जिसका अर्थ है: किसी ऐसी चीज को छोड़ने के लिए जो मूल्य या प्रकार की परिभाषा के लिए आवश्यक नहीं है, ताकि यह एक तर्क के रूप में अमूर्त के उपयोगकर्ता द्वारा विविध / प्रदान किया जा सके। ।)

यहाँ कुछ उदाहरण हैं (ईमेल द्वारा लुत्ज़ के सवालों से प्रेरित) उचित, प्रथम-क्रम और उच्च-क्रम मान और प्रकार:

                   proper    first-order           higher-order

values             10        (x: Int) => x         (f: (Int => Int)) => f(10)
types (classes)    String    List                  Functor
types              String    ({type λ[x] = x})#λ   ({type λ[F[x]] = F[String]})#λ

जहाँ प्रयुक्त वर्गों को परिभाषित किया गया था:

class String
class List[T]
class Functor[F[_]]

परिभाषित करने वाली कक्षाओं के माध्यम से अप्रत्यक्ष रूप से बचने के लिए, आपको किसी तरह अनाम कार्यों को व्यक्त करने की आवश्यकता है, जो सीधे स्काला में व्यक्त नहीं हैं, लेकिन आप संरचनात्मक प्रकारों का उपयोग बहुत अधिक सिंथैटिक ओवरहेड के बिना कर सकते हैं ( -स्टाइल https://stackoverflow.com के कारण है) / उपयोगकर्ता / 160378 / पूर्वव्यापी afaik):

गुमनाम प्रकार के कार्यों का समर्थन करने वाले स्काला के कुछ काल्पनिक भविष्य के संस्करण में, आप उदाहरणों से अंतिम पंक्ति को छोटा कर सकते हैं:

types (informally) String    [x] => x              [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be

(एक व्यक्तिगत टिप्पणी पर, मुझे कभी भी "उच्च-प्रकार के प्रकारों" के बारे में बात करने पर पछतावा होता है, वे सभी प्रकार के होते हैं! जब आपको पूरी तरह से अवहेलना करने की आवश्यकता होती है, तो मैं आपको "टाइप कंस्ट्रक्टर पैरामीटर", "टाइप कंस्ट्रक्टर सदस्य" जैसी बातें कहने का सुझाव देता हूं। , या "टाइप कंस्ट्रक्टर उर्फ", इस बात पर जोर देने के लिए कि आप केवल उचित प्रकारों के बारे में बात नहीं कर रहे हैं।)

पीएस: आगे के मामलों को जटिल करने के लिए, "पॉलीमॉर्फिक" एक अलग तरीके से अस्पष्ट है, क्योंकि एक पॉलीमॉर्फिक प्रकार का मतलब कभी-कभी एक सार्वभौमिक रूप से निर्धारित प्रकार होता है, जैसे कि Forall T, T => T, यह एक उचित प्रकार है, क्योंकि यह पॉलिफ़िक मानों को वर्गीकृत करता है (स्काला में, यह मान हो सकता है) संरचनात्मक प्रकार के रूप में लिखा {def apply[T](x: T): T = x})


1
इसे भी देखें: adriaanm.github.com/research/2010/10/06/…
Adriaan Moors

5
Adriaan का "टाइप कंस्ट्रक्टर पॉलिमोर्फिज्म
स्टीवन शॉ

मैं इसे उच्च
दयालु के

110

(यह उत्तर कुछ चित्रमय और ऐतिहासिक जानकारी द्वारा एड्रियन मूर उत्तर को सजाने का प्रयास है।)

उच्च प्रकार के प्रकार 2.5 के बाद से स्काला का हिस्सा हैं।

  • इससे पहले कि अब तक जावा के रूप में स्काला, टाइप कंस्ट्रक्टर (जावा में "जेनेरिक") को टाइप कंस्ट्रक्टर के रूप में इस्तेमाल करने की अनुमति नहीं देता था। जैसे

     trait Monad [M[_]]

    संभव नहीं था।

    स्काला 2.5 में उच्च स्तर पर प्रकारों को वर्गीकृत करने की क्षमता (जिसे टाइप कंस्ट्रक्शन पॉलिमोरिज़्म के रूप में जाना जाता है ) द्वारा टाइप सिस्टम को बढ़ाया गया था । इन वर्गीकरणों को प्रकार के रूप में जाना जाता है।

    प्रकार और तरह का अहसास, "व्युत्पन्न ** से" एक उच्चतर प्रकार का " (चित्र एक उच्च प्रकार की पीढ़ी से प्राप्त )

    परिणाम यह है, कि टाइप कंस्ट्रक्टर (जैसे List) को टाइप कंस्ट्रक्टर के प्रकार पैरामीटर स्थिति में अन्य प्रकारों के रूप में इस्तेमाल किया जा सकता है और इसलिए वे स्केल 2.5 के बाद से प्रथम श्रेणी के प्रकार बन गए। (फ़ंक्शन के समान जो स्काला में प्रथम श्रेणी के मान हैं)।

    उच्च प्रकार का समर्थन करने वाली एक प्रकार की प्रणाली के संदर्भ में, हम उचित प्रकार , प्रकार जैसे Intया List[Int]पहले-प्रकार के प्रकार जैसे Listऔर उच्च प्रकार के प्रकार जैसे ( Functorया Monadप्रकार जो सार से अधिक प्रकार के होते हैं) को अलग कर सकते हैं।

    दूसरी तरफ जावा का प्रकार सिस्टम प्रकार का समर्थन नहीं करता है और इसलिए "उच्च प्रकार" का कोई प्रकार नहीं है।

    तो यह सहायक प्रकार प्रणाली की पृष्ठभूमि के खिलाफ देखा जाना चाहिए।

  • स्काला के मामले में आप अक्सर एक प्रकार के निर्माणकर्ता जैसे उदाहरण देखते हैं

     trait Iterable[A, Container[_]]

    "उच्च प्रकार के प्रकार" शीर्षक के साथ, जेनेरिक प्रोग्रामर के लिए स्केल में , खंड 4.3

    इसे कभी-कभी missleading है क्योंकि कई का उल्लेख Containerके रूप में उच्च kinded प्रकार और नहीं Iterableहै, लेकिन क्या है और अधिक सटीक है,

    के उपयोग के Containerलिए एक उच्च kinded (उच्च क्रम) के रूप में प्रकार निर्माता पैरामीटर यहाँ लिखें Iterable


80

तरह तरह साधारण प्रकार के Intऔर Char, जिसका उदाहरणों मान होते हैं, है *। की तरह एकल प्रकार निर्माताओं की तरह Maybeहै * -> *; बाइनरी टाइप कंस्ट्रक्टर जैसे Either( करी ) तरह के होते हैं * -> * -> *, और इसी तरह । आप की तरह प्रकार देख सकते हैं Maybeऔर Eitherके रूप में प्रकार स्तर के कार्यों: वे एक या अधिक प्रकार लेते हैं, और एक प्रकार लौट आते हैं।

एक समारोह है उच्च क्रम अगर यह एक है आदेश 1 से अधिक है, जहां आदेश (अनौपचारिक) नेस्टिंग गहराई, बाईं ओर, समारोह तीर की है:

  • आदेश 0: 1 :: Int
  • आदेश 1: chr :: Int -> Char
  • आदेश 2: fix :: (a -> a) -> a,map :: (a -> b) -> [a] -> [b]
  • आदेश 3: ((A -> B) -> C) -> D
  • आदेश 4: (((A -> B) -> C) -> D) -> E

तो, लंबी कहानी छोटी, एक उच्च- प्रकार का प्रकार केवल एक प्रकार-स्तरीय उच्च-क्रम फ़ंक्शन है।

  • आदेश 0: Int :: *
  • आदेश 1: Maybe :: * -> *
  • आदेश 2: Functor :: (* -> *) -> Constraint-उच्चर की तरह: टाइपरी की कमी के लिए एकरी प्रकार के कंस्ट्रक्टर्स को रूपांतरित करता है

ठीक है मुझे मिल गया, तब (* ⇒ *) ⇒ * और (* ⇒ *) ⇒ (* ⇒ *) के लिए Scala में एक उदाहरण क्या होगा? क्या लांडे का फ़नकार पहली श्रेणी में या दूसरे में फिट होगा?
लूत्ज

1
@ लुट्ज़: यह पहली श्रेणी में होगा: एक प्रकार के कंस्ट्रक्टर से एक Functorउचित प्रकार (अच्छी तरह से, विशेषता, लेकिन एक ही विचार) पैदा करता है । Functor[F[_]]F
जॉन पूर्डी

1
@ जॉन: एक बहुत ही व्यावहारिक पोस्ट, धन्यवाद। क्या स्कैला में टाइप कन्वर्टर (* => *) => (* => *)व्यक्त किया जा सकता है? यदि नहीं, तो किसी अन्य भाषा में?
यूजेन लाबुन

@JonPurdy करी के * ⇒ * ⇒ *साथ तुलना बहुत मददगार है। धन्यवाद!
लिफू हुआंग

(* ⇒ *) ⇒ (* ⇒ *)वर्तनी भी हो सकती है (* ⇒ *) ⇒ * ⇒ *। इसे स्काला में व्यक्त किया जा सकता है Foo[F[_], T]। यह एक प्रकार का प्रकार है newtype Twice f a = Twice (f (f a))(जैसे हास्केल में) (जैसे, Twice Maybe IntMaybe (Maybe Int), Twice [] Chartype [[Char]]) या मुफ्त मोनाड जैसा कुछ और दिलचस्प data Free f a = Pure a | Free (f (Free f a))
जॉन पुरडी

37

मैं कहूंगा: एक उच्च दयालु प्रकार सार । जैसे विचार करें

trait Functor [F[_]] {
   def map[A,B] (fn: A=>B)(fa: F[A]): F[B]
}

यहाँ Functorएक "उच्च प्रकार" है (जैसा कि प्रयोग किया जाता है) "जेनरिक ऑफ़ ए हायर " पेपर )। यह एक ठोस ("प्रथम-क्रम") प्रकार का कंस्ट्रक्टर नहीं है List( जैसे कि उचित प्रकार से अधिक सार)। यह सभी यूनरी ("प्रथम-क्रम") प्रकार के कंस्ट्रक्टरों पर सार करता है (जैसा कि इसके साथ दर्शाया गया है F[_])।

या इसे दूसरे तरीके से रखने के लिए: जावा में, हमारे पास स्पष्ट रूप से निर्माता हैं (जैसे List<T> ), लेकिन हमारे पास कोई "उच्च प्रकार के प्रकार" नहीं हैं, क्योंकि हम उन पर सार नहीं कर सकते हैं (उदाहरण के लिए, हम Functorऊपर परिभाषित इंटरफ़ेस नहीं लिख सकते हैं - कम से कम सीधे नहीं )।

शब्द "उच्च क्रम (प्रकार के निर्माणकर्ता) बहुरूपता" का उपयोग उन प्रणालियों का वर्णन करने के लिए किया जाता है जो "उच्च प्रकार" का समर्थन करते हैं।


यह मैंने सोचा था, लेकिन यह जॉन के जवाब का खंडन करने लगता है, जहां "कंक्रीट प्रकार का निर्माणकर्ता" पहले से ही "उच्च प्रकार का" है।
लूत्ज

3
हाँ। जॉन के उत्तर के अनुसार (जैसा कि मैं इसे समझता हूं) List<T>जावा में एक एकरी प्रकार का निर्माता होगा क्योंकि यह स्पष्ट रूप से प्रकार है * -> *। जॉन के जवाब में जो बात याद आ रही है, वह यह है कि आप इसे पूरी तरह से *टाइप करने के लिए "पूरी बात" (और सिर्फ जावा में दूसरा नहीं ) पर सार कर सकते हैं।
लांडेय

@Landai: कागज सामान्य प्रोग्रामर के लिए स्काला धारा 4.3 में विशेषता Iterable [एक, कंटेनर [_]] एक उच्च kinded प्रकार होना (हालांकि यह स्पष्ट नहीं है अगर इटरेटर या कंटेनर का मतलब है) से पता चलता है, जहां दूसरे पक्ष पर vero690 में खंड 2.3.1 कुछ (जैसे - * - *) -> * के लिए उच्च-प्रकार के टाइप कंस्ट्रक्टर शब्द का उपयोग करता है (टाइप ऑपरेटर जो उच्च-क्रम प्रकार के निर्माता के साथ मानकीकृत होता है) जो कि इटरेटर या आपके फ़ंक्टर विशेषता के समान दिखता है।
लुट्ज़

1
यह शायद सही है, लेकिन मुझे लगता है कि हम यहाँ बालों को विभाजित करना शुरू कर रहे हैं। उच्च प्रकार के प्रकारों के बारे में महत्वपूर्ण बिंदु यह है कि न केवल प्रकार के निर्माता शामिल हैं (आदेश एक प्रकार के निर्माण बहुरूपता), लेकिन यह कि हम उस प्रकार के निर्माणकर्ताओं (उच्च क्रम प्रकार के निर्माण बहुरूपता) के ठोस प्रकार पर अमूर्त करने में सक्षम हैं। हमारे पास प्रतिबंधों (प्रकारों और प्रकार के निर्माणकर्ताओं) के बिना जो कुछ भी हम चाहते हैं, उस पर अमल करने की क्षमता है, जो उस सुविधा के सभी संभावित संस्करणों को नाम देना कम दिलचस्प बनाता है। और यह मेरे दिमाग को चोट पहुँचाता है।
लांडेय

2
सामान्य तौर पर यहां परिभाषाओं और संदर्भों को अलग करना महत्वपूर्ण है। परिभाषा def succ(x: Int) = x+1"वैल्यू कंस्ट्रक्टर" का परिचय देती है (इसके लिए मेरा दूसरा जवाब देखें कि मेरा क्या मतलब है) succ(कोई भी इस मूल्य को succ (x: Int) के रूप में संदर्भित नहीं करेगा)। सादृश्य से, Functorआपके उत्तर में परिभाषित (वास्तव में उच्चतर) प्रकार है। फिर से, आपको इसका संदर्भ नहीं देना चाहिए Functor[F[_]](क्या है F? क्या है _? वे दायरे में नहीं हैं! दुर्भाग्य से, अस्तित्व के लिए सिंटैक्टिक चीनी यहाँ पानी F[_]कम कर देती है F[T forSome {type T}])
एड्रियन मॉयर्स

0

स्काला आरईपीएल :kindकमांड प्रदान करता है

scala> :help kind

:kind [-v] <type>
Displays the kind of a given type.

उदाहरण के लिए,

scala> trait Foo[A]
trait Foo

scala> trait Bar[F[_]]
trait Bar

scala> :kind -v Foo
Foo's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.

scala> :kind -v Foo[Int]
Foo[Int]'s kind is A
*
This is a proper type.

scala> :kind -v Bar
Bar's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.

scala> :kind -v Bar[Foo]
Bar[Foo]'s kind is A
*
This is a proper type.

:helpइसलिए मुझे लगता है कि यह अपनी संपूर्णता में यहाँ लायक पोस्टिंग यह है स्पष्ट परिभाषाओं प्रदान करता है (स्काला 2.13.2)

scala> :help kind

:kind [-v] <type>
Displays the kind of a given type.

    -v      Displays verbose info.

"Kind" is a word used to classify types and type constructors
according to their level of abstractness.

Concrete, fully specified types such as `Int` and `Option[Int]`
are called "proper types" and denoted as `A` using Scala
notation, or with the `*` symbol.

    scala> :kind Option[Int]
    Option[Int]'s kind is A

In the above, `Option` is an example of a first-order type
constructor, which is denoted as `F[A]` using Scala notation, or
* -> * using the star notation. `:kind` also includes variance
information in its output, so if we ask for the kind of `Option`,
we actually see `F[+A]`:

    scala> :k -v Option
    Option's kind is F[+A]
    * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.

When you have more complicated types, `:kind` can be used to find
out what you need to pass in.

    scala> trait ~>[-F1[_], +F2[_]] {}
    scala> :kind ~>
    ~>'s kind is X[-F1[A1],+F2[A2]]

This shows that `~>` accepts something of `F[A]` kind, such as
`List` or `Vector`. It's an example of a type constructor that
abstracts over type constructors, also known as a higher-order
type constructor or a higher-kinded type.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.