खोज…


टिप्पणियों

ये भाषा एक्सटेंशन आमतौर पर ग्लासगो हास्केल कंपाइलर (जीएचसी) का उपयोग करते समय उपलब्ध होते हैं क्योंकि वे अनुमोदित हास्केल 2010 भाषा रिपोर्ट का हिस्सा नहीं होते हैं। इन एक्सटेंशनों का उपयोग करने के लिए, किसी को एक झंडे का उपयोग करके या तो कंपाइलर को सूचित करना चाहिए या किसी फ़ाइल में module कीवर्ड से पहले एक LANGUAGE प्रोग्राम रखना चाहिए। आधिकारिक दस्तावेज जीसीएच उपयोगकर्ता गाइड के खंड 7 में पाया जा सकता है।

LANGUAGE प्रोग्राम का प्रारूप {-# LANGUAGE ExtensionOne, ExtensionTwo ... #-} । वह शाब्दिक {-# जिसके बाद LANGUAGE उसके बाद एक्सटेंशन की अल्पविराम से अलग सूची है, और अंत में समापन #-} । एक LANGUAGE कई LANGUAGE कार्यक्रम रखे जा सकते हैं।

MultiParamTypeClasses

यह एक बहुत ही सामान्य विस्तार है जो कई प्रकार के मापदंडों के साथ टाइप कक्षाएं देता है। आप एमपीटीसी को प्रकारों के बीच के संबंध के रूप में सोच सकते हैं।

{-# LANGUAGE MultiParamTypeClasses #-}

class Convertable a b where
    convert :: a -> b

instance Convertable Int Float where
    convert i = fromIntegral i

मापदंडों का क्रम मायने रखता है।

एमपीटीसी कभी-कभी टाइप परिवारों के साथ प्रतिस्थापित किया जा सकता है।

FlexibleInstances

नियमित उदाहरणों की आवश्यकता होती है:

All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.

इसका मतलब है कि, उदाहरण के लिए, जब आप [a] लिए एक उदाहरण बना सकते हैं, तो आप विशेष रूप से [Int] लिए एक उदाहरण नहीं बना सकते हैं; FlexibleInstances राहत मिलती है:

class C a where

-- works out of the box
instance C [a] where

-- requires FlexibleInstances
instance C [Int] where

OverloadedStrings

आम तौर पर, हास्केल में स्ट्रिंग शाब्दिक में एक प्रकार का String (जो [Char] लिए एक प्रकार का उपनाम है)। हालांकि यह छोटे, शैक्षिक कार्यक्रमों के लिए समस्या नहीं है, लेकिन वास्तविक दुनिया के अनुप्रयोगों में अक्सर Text या ByteString जैसे अधिक कुशल भंडारण की आवश्यकता होती है।

OverloadedStrings बस के प्रकार को शाब्दिक रूप से बदलता है

"test" :: Data.String.IsString a => a

उन्हें इस तरह के प्रकार की अपेक्षा करने वाले कार्यों के लिए सीधे पारित किया जाना। कई लाइब्रेरी इस इंटरफ़ेस को अपने स्ट्रिंग-जैसे प्रकारों के लिए कार्यान्वित करते हैं जिनमें Data.Text और Data.ByteString शामिल हैं जो दोनों [Char] पर निश्चित समय और स्थान लाभ प्रदान करते हैं।

OverloadedStrings कुछ अनूठे उपयोग भी हैं जैसे कि Postgresql-simple पुस्तकालय से जो एसक्यूएल प्रश्नों को सामान्य स्ट्रिंग की तरह दोहरे उद्धरणों में लिखने की अनुमति देता है, लेकिन अनुचित इंजेक्शन के खिलाफ सुरक्षा प्रदान करता है, SQL इंजेक्शन हमलों का एक कुख्यात स्रोत।

IsString वर्ग का एक उदाहरण बनाने के लिए आपको fromString फ़ंक्शन का fromString करना होगा। उदाहरण :

data Foo = A | B | Other String deriving Show

instance IsString Foo where
  fromString "A" = A
  fromString "B" = B
  fromString xs  = Other xs

tests :: [ Foo ]
tests = [ "A", "B", "Testing" ]

लिंडन Maydwell (का यह उदाहरण शिष्टाचार sordina GitHub पर) पाया यहाँ

TupleSections

एक सिंटैक्टिक एक्सटेंशन जो एक प्रकार से ट्यूपल कंस्ट्रक्टर (जो एक ऑपरेटर है) को आवेदन करने की अनुमति देता है:

(a,b) == (,) a b

-- With TupleSections
(a,b) == (,) a b == (a,) b == (,b) a

एन-tuples

यह दो से अधिक की संख्या के साथ टुपल्स के लिए भी काम करता है

(,2,) 1 3 == (1,2,3)

मानचित्रण

यह उन अन्य स्थानों पर उपयोगी हो सकता है, जहां वर्गों का उपयोग किया जाता है:

map (,"tag") [1,2,3] == [(1,"tag"), (2, "tag"), (3, "tag")]

इस विस्तार के बिना उपरोक्त उदाहरण इस तरह दिखेगा:

map (\a -> (a, "tag")) [1,2,3]

UnicodeSyntax

एक एक्सटेंशन जो आपको कुछ अंतर्निहित ऑपरेटरों और नामों के बदले में यूनिकोड वर्णों का उपयोग करने की अनुमति देता है।

ASCII यूनिकोड का प्रयोग करें (रों)
:: प्रकार है
-> फंक्शन टाइप, लंबदा, case ब्रांच आदि।
=> वर्ग की कमी
forall स्पष्ट बहुरूपता
<- do अंकन
* प्रकार (या प्रकार) के प्रकार (जैसे, Int :: ★ )
>- proc अंकन के लिए Arrows
-< proc अंकन के लिए Arrows
>>- proc अंकन के लिए Arrows
-<< proc अंकन के लिए Arrows

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

runST :: (forall s. ST s a) -> a

बन जाएगा

runST ∷ (∀ s. ST s a) → a

ध्यान दें कि * बनाम उदाहरण थोड़ा अलग है: क्योंकि * आरक्षित नहीं है, भी गुणा, या किसी अन्य फ़ंक्शन नाम (*) , और इसके विपरीत के रूप में * उसी तरह काम करता है। उदाहरण के लिए:

ghci> 2 ★ 3
6
ghci> let (*) = (+) in 2 ★ 3
5
ghci> let (★) = (-) in 2 * 3
-1

BinaryLiterals

स्टैंडर्ड हास्केल आपको दशमलव (पूर्णांक के बिना) में पूर्णांक शाब्दिक लिखने की अनुमति देता है, हेक्साडेसिमल ( 0x या 0X से पहले), और ऑक्टल ( 0o या 0O द्वारा पूर्ववर्ती)। BinaryLiterals विस्तार द्विआधारी का विकल्प (से पहले कहते हैं 0b या 0B )।

0b1111 == 15     -- evaluates to: True

ExistentialQuantification

यह एक प्रकार प्रणाली विस्तार है जो प्रकार है कि existentially मात्रा निर्धारित कर रहे हैं, या दूसरे शब्दों में अनुमति देता है, प्रकार चर है कि केवल रनटाइम पर instantiated हो है।

अस्तित्वगत प्रकार का एक मान OO भाषाओं में एक अमूर्त-बेस-क्लास संदर्भ के समान है: आप इसमें सटीक प्रकार नहीं जानते हैं, लेकिन आप प्रकारों के वर्ग को बाधित कर सकते हैं।

data S = forall a. Show a => S a

या समकक्ष, GADT सिंटैक्स के साथ:

{-# LANGUAGE GADTs #-}
data S where
   S :: Show a => a -> S

अस्तित्ववादी प्रकार लगभग-विषम कंटेनरों जैसी चीजों के लिए दरवाजा खोलते हैं: जैसा कि ऊपर कहा गया है, वास्तव में एक S मूल्य में विभिन्न प्रकार हो सकते हैं, लेकिन उनमें से सभी को एन show जा सकता है, इसलिए आप भी कर सकते हैं

instance Show S where
    show (S a) = show a   -- we rely on (Show a) from the above

अब हम ऐसी वस्तुओं का संग्रह बना सकते हैं:

ss = [S 5, S "test", S 3.0]

जो हमें बहुरूपी व्यवहार का उपयोग करने की भी अनुमति देता है:

mapM_ print ss

अस्तित्व बहुत शक्तिशाली हो सकते हैं, लेकिन ध्यान दें कि वे वास्तव में हास्केल में बहुत बार आवश्यक नहीं हैं। उपरोक्त उदाहरण में, आप वास्तव में Show उदाहरण के साथ कर सकते हैं शो (duh!) मान है, अर्थात एक स्ट्रिंग प्रतिनिधित्व बनाएँ। पूरे S प्रकार में वास्तव में उतनी ही जानकारी होती है जितनी कि स्ट्रिंग आपको दिखाते समय मिलती है। इसलिए, आमतौर पर उस स्ट्रिंग को तुरंत स्टोर करना बेहतर होता है, खासकर जब से हास्केल आलसी होता है और इसलिए पहले से ही स्ट्रिंग वैसे भी केवल एक अनवैलिड थंक होगा।

दूसरी ओर, अस्तित्ववादी कुछ अनोखी समस्याएं पैदा करते हैं। उदाहरण के लिए, प्रकार की जानकारी एक अस्तित्व में "छिपी" है। यदि आप S मान पर प्रतिमान-मिलान करते हैं, तो आपके पास समाहित प्रकार का दायरा होगा (अधिक सटीक रूप से, इसका उदाहरण Show ), लेकिन यह जानकारी कभी भी इसके दायरे से बच नहीं सकती है, इसलिए यह "गुप्त समाज" का एक सा बन जाता है: संकलक उन मानों को छोड़ कर कुछ भी नहीं होने देता है , जिनके प्रकार पहले से ही बाहर से ज्ञात हैं। यह अजीब त्रुटियों को जन्म दे सकता है जैसे कि Couldn't match type 'a0' with '()' 'a0' is untouchable


Ric इसके विपरीत साधारण पैरामीट्रिक बहुरूपता है, जो आम तौर पर संकलन समय (पूर्ण प्रकार के उन्मूलन की अनुमति) में हल किया जाता है।


अस्तित्व-प्रकार रैंक-एन प्रकार से भिन्न होते हैं - ये एक्सटेंशन हैं, मोटे तौर पर बोल, एक दूसरे से दोहरे: वास्तव में एक अस्तित्वगत प्रकार के मूल्यों का उपयोग करने के लिए, आपको उदाहरण में show के लिए एक (संभवतः विवश-) बहुरूपिक फ़ंक्शन की आवश्यकता होती है। एक पॉलीमॉर्फिक फ़ंक्शन सार्वभौमिक रूप से परिमाणित है, अर्थात यह किसी दिए गए वर्ग में किसी भी प्रकार के लिए काम करता है, जबकि अस्तित्वगत मात्रा का मतलब है कि यह कुछ विशेष प्रकार के लिए काम करता है जो कि एक प्राथमिक अज्ञात है। यदि आपके पास एक बहुरूपी कार्य है, तो यह पर्याप्त है, हालांकि {-# LANGUAGE Rank2Types #-} कार्यों जैसे कि तर्कों को पारित करने के लिए, आपको {-# LANGUAGE Rank2Types #-} : की आवश्यकता है।

genShowSs :: (∀ x . Show x => x -> String) -> [S] -> [String]
genShowSs f = map (\(S a) -> f a)

LambdaCase

एक वाक्यात्मक विस्तार जो आपको \arg -> case arg of स्थान पर \arg -> case arg of \case लिखने देता \arg -> case arg of

निम्नलिखित फ़ंक्शन परिभाषा पर विचार करें:

dayOfTheWeek :: Int -> String
dayOfTheWeek 0 = "Sunday"
dayOfTheWeek 1 = "Monday"
dayOfTheWeek 2 = "Tuesday"
dayOfTheWeek 3 = "Wednesday"
dayOfTheWeek 4 = "Thursday"
dayOfTheWeek 5 = "Friday"
dayOfTheWeek 6 = "Saturday"

यदि आप फ़ंक्शन का नाम दोहराने से बचना चाहते हैं, तो आप कुछ ऐसा लिख सकते हैं:

dayOfTheWeek :: Int -> String
dayOfTheWeek i = case i of
    0 -> "Sunday"
    1 -> "Monday"
    2 -> "Tuesday"
    3 -> "Wednesday"
    4 -> "Thursday"
    5 -> "Friday"
    6 -> "Saturday"

लेम्बडाकैस एक्सटेंशन का उपयोग करते हुए, आप तर्क को नाम दिए बिना फ़ंक्शन अभिव्यक्ति के रूप में लिख सकते हैं:

{-# LANGUAGE LambdaCase #-}

dayOfTheWeek :: Int -> String
dayOfTheWeek = \case
    0 -> "Sunday"
    1 -> "Monday"
    2 -> "Tuesday"
    3 -> "Wednesday"
    4 -> "Thursday"
    5 -> "Friday"
    6 -> "Saturday"

RankNTypes

निम्नलिखित स्थिति की कल्पना करें:

foo :: Show a => (a -> String) -> String -> Int -> IO ()
foo show' string int = do
   putStrLn (show' string)
   putStrLn (show' int)

यहां, हम एक फ़ंक्शन में पास करना चाहते हैं जो एक मान को स्ट्रिंग में परिवर्तित करता है, उस फ़ंक्शन को एक स्ट्रिंग पैरामीटर और इंट पैरामीटर दोनों पर लागू करें और उन दोनों को प्रिंट करें। मेरे दिमाग में, कोई कारण नहीं है कि यह विफल होना चाहिए! हमारे पास एक फ़ंक्शन है जो दोनों प्रकार के मापदंडों पर काम करता है जो हम पास कर रहे हैं।

दुर्भाग्य से, यह चेक टाइप नहीं करेगा! जीएचसी फ़ंक्शन बॉडी में अपनी पहली घटना के आधार पर a प्रकार को संक्रमित करता है। जैसे ही, हमने मारा:

putStrLn (show' string)

जीएचसी वह show' :: String -> String , चूंकि string एक String । यह show' int कोशिश करते हुए आगे बढ़ना होगा।

RankNTypes आपको निम्न प्रकार के हस्ताक्षर लिखने के बजाय, show' प्रकार को संतुष्ट करने वाले सभी कार्यों पर निर्भर करता है:

foo :: (forall a. Show a => (a -> String)) -> String -> Int -> IO ()

यह रैंक 2 बहुरूपता है: हम जोर देते हुए कर रहे हैं कि show' सभी के लिए समारोह होगा काम a हमारे समारोह के भीतर है, और पिछले कार्यान्वयन अब काम करता है।

RankNTypes एक्सटेंशन, RankNTypes मनमाने तरीके से घोंसले के शिकार की अनुमति देता है forall ... प्रकार के हस्ताक्षर में ब्लॉक। दूसरे शब्दों में, यह रैंक एन बहुरूपता की अनुमति देता है।

OverloadedLists

जीएचसी 7.8 में जोड़ा गया

OverloadedLists, के समान OverloadedStrings , की अनुमति देता है के रूप में इस सूची शाब्दिक desugared जा करने के लिए:

[]          -- fromListN 0 []
[x]         -- fromListN 1 (x : [])
[x .. ]     -- fromList (enumFrom x)

यह Set , Vector और Map जैसे प्रकारों के साथ काम करते समय काम आता है।

['0' .. '9']             :: Set Char
[1 .. 10]                :: Vector Int
[("default",0), (k1,v1)] :: Map String Int
['a' .. 'z']             :: Text

इस विस्तार के साथ GHC.Exts में IsList वर्ग का उपयोग करने का इरादा है।

IsList एक प्रकार के फ़ंक्शन, Item और तीन कार्यों से सुसज्जित है, fromList :: [Item l] -> l , toList :: l -> [Item l] और fromListN :: Int -> [Item l] -> l जहाँ fromListN वैकल्पिक है। विशिष्ट कार्यान्वयन हैं:

instance IsList [a] where
  type Item [a] = a
  fromList = id
  toList   = id

instance (Ord a) => IsList (Set a) where
  type Item (Set a) = a
  fromList = Set.fromList
  toList   = Set.toList

ओवरलोडेडलिस्ट्स से लिए गए उदाहरण - जीएचसी

FunctionalDependencies

यदि आपके पास a, b, c, और x के साथ मल्टी-पैरामीटर टाइप-क्लास है, तो यह एक्सटेंशन आपको यह व्यक्त करने देता है कि टाइप x को विशिष्ट रूप से a, b और c से पहचाना जा सकता है:

class SomeClass a b c x | a b c -> x where ...

इस तरह के वर्ग की एक आवृत्ति की घोषणा करते समय, यह सुनिश्चित करने के लिए अन्य सभी उदाहरणों के खिलाफ जाँच की जाएगी कि कार्यात्मक निर्भरता रखती है, अर्थात समान abc साथ कोई अन्य उदाहरण नहीं है, लेकिन अलग-अलग x मौजूद हैं।

आप अल्पविराम से अलग की गई सूची में कई निर्भरताएँ निर्दिष्ट कर सकते हैं:

class OtherClass a b c d | a b -> c d, a d -> b where ...

एमटीएल में उदाहरण के लिए हम देख सकते हैं:

class MonadReader r m| m -> r where ...
instance MonadReader r ((->) r) where ...

अब, यदि आपके पास प्रकार का मान है MonadReader a ((->) Foo) => a , संकलक अनुमान लगा सकता है कि a ~ Foo , क्योंकि दूसरा तर्क पूरी तरह से पहले को निर्धारित करता है, और तदनुसार प्रकार को सरल करेगा।

SomeClass वर्ग तर्कों के एक समारोह के रूप में सोचा जा सकता abc कि में परिणाम x । इस तरह की कक्षाओं का उपयोग टाइपसिस्टम में कम्प्यूटेशन करने के लिए किया जा सकता है।

GADTs

परम्परागत बीजगणितीय डेटाेटिप्स उनके प्रकार चर में पैरामीट्रिक हैं। उदाहरण के लिए, यदि हम ADT को परिभाषित करते हैं

data Expr a = IntLit Int 
            | BoolLit Bool 
            | If (Expr Bool) (Expr a) (Expr a)

इस उम्मीद के साथ कि यह गैर-अच्छी तरह से टाइप किए गए सशर्त नियमों का पालन करेगा, यह IntLit :: Int -> Expr a के प्रकार के बाद से अपेक्षित व्यवहार नहीं करेगा IntLit :: Int -> Expr a रूप से निर्धारित है: किसी भी विकल्प के a , यह प्रकार का एक मान पैदा करता है Expr a । विशेष रूप से, के लिए a ~ Bool , हमारे पास IntLit :: Int -> Expr Bool हमें की तरह कुछ का निर्माण करने की अनुमति देता है, If (IntLit 1) e1 e2 है जो के प्रकार के If निर्माता से इनकार करने के लिए कोशिश कर रहा था।

सामान्यीकृत बीजीय डेटा प्रकार हमें डेटा निर्माता के परिणामी प्रकार को नियंत्रित करने की अनुमति देता है ताकि वे केवल पैरामीट्रिक न हों। हम अपने Expr प्रकार को इस तरह GADT के रूप में फिर से लिख सकते हैं:

data Expr a where
  IntLit :: Int -> Expr Int
  BoolLit :: Bool -> Expr Bool
  If :: Expr Bool -> Expr a -> Expr a -> Expr a

यहां, कंस्ट्रक्टर IntLit का प्रकार Int -> Expr Int , और इसलिए IntLit 1 :: Expr Bool टाइपकास्ट नहीं होगा।

एक जीएडीटी मूल्य पर पैटर्न का मिलान लौटे हुए शब्द के प्रकार को परिष्कृत करता है। उदाहरण के लिए, Expr a लिए मूल्यांकनकर्ता को इस तरह लिखना संभव है:

crazyEval :: Expr a -> a
crazyEval (IntLit x) = 
   -- Here we can use `(+)` because x :: Int
   x + 1 
crazyEval (BoolLit b) = 
   -- Here we can use `not` because b :: Bool
   not b
crazyEval (If b thn els) = 
  -- Because b :: Expr Bool, we can use `crazyEval b :: Bool`.
  -- Also, because thn :: Expr a and els :: Expr a, we can pass either to 
  -- the recursive call to `crazyEval` and get an a back
  crazyEval $ if crazyEval b then thn else els 

ध्यान दें कि हम उपरोक्त परिभाषाओं में (+) का उपयोग करने में सक्षम हैं क्योंकि जब IntLit x पैटर्न से मेल खाता है, तो हम यह भी सीखते हैं कि a ~ Int (इसी तरह not और if_then_else_ जब a ~ Bool )।

ScopedTypeVariables

ScopedTypeVariables आपको घोषणा के अंदर सार्वभौमिक रूप से मात्रात्मक प्रकारों को संदर्भित करते हैं। अधिक स्पष्ट होना:

import Data.Monoid

foo :: forall a b c. (Monoid b, Monoid c) => (a, b, c) -> (b, c) -> (a, b, c)
foo (a, b, c) (b', c') = (a :: a, b'', c'')
    where (b'', c'') = (b <> b', c <> c') :: (b, c)

महत्वपूर्ण बात यह है कि हम का उपयोग कर सकते है a , b और c के लिए संकलक हिदायत घोषणा के subexpressions में (टपल में where खंड और पहले a अंतिम परिणाम में)। व्यवहार में, ScopedTypeVariables जटिल कार्यों को भागों के योग के रूप में लिखने में सहायता करते हैं, जिससे प्रोग्रामर को मध्यवर्ती मानों के लिए टाइप हस्ताक्षर जोड़ने की अनुमति मिलती है जिसमें ठोस प्रकार नहीं होते हैं।

PatternSynonyms

पैटर्न समानार्थक शब्द के समान पैटर्न के सार हैं कैसे फ़ंक्शन अभिव्यक्ति के सार हैं।

इस उदाहरण के लिए, आइए इंटरफेस Data.Sequence को देखें, और देखते हैं कि पैटर्न समानार्थक शब्द के साथ इसे कैसे बेहतर बनाया जा सकता है। Seq प्रकार एक डेटा प्रकार है, जो आंतरिक रूप से, विभिन्न परिचालनों के लिए अच्छी स्पर्शोन्मुख जटिलता को प्राप्त करने के लिए एक जटिल प्रतिनिधित्व का उपयोग करता है, विशेष रूप से O (1) (un) कंसिंग और (un) स्नोकिंग दोनों।

लेकिन यह प्रतिनिधित्व नाकाफी है और हास्केल के प्रकार प्रणाली में इसके कुछ अपरिवर्तनों को व्यक्त नहीं किया जा सकता है। इसके कारण, Seq प्रकार उपयोगकर्ताओं के बीच एक अमूर्त प्रकार के रूप में प्रकट होता है, साथ ही साथ इनवेरिएंट-प्रोटेक्टिंग एक्सेसर और कंस्ट्रक्टर फ़ंक्शंस:

empty :: Seq a

(<|) :: a -> Seq a -> Seq a
data ViewL a = EmptyL | a :< (Seq a)
viewl :: Seq a -> ViewL a

(|>) :: Seq a -> a -> Seq a 
data ViewR a = EmptyR | (Seq a) :> a 
viewr :: Seq a -> ViewR a

लेकिन इस इंटरफ़ेस का उपयोग करना थोड़ा बोझिल हो सकता है:

uncons :: Seq a -> Maybe (a, Seq a)
uncons xs = case viewl xs of
    x :< xs' -> Just (x, xs')
    EmptyL -> Nothing

हम कुछ हद तक इसे साफ करने के लिए व्यू पैटर्न का उपयोग कर सकते हैं:

{-# LANGUAGE ViewPatterns #-}

uncons :: Seq a -> Maybe (a, Seq a)
uncons (viewl -> x :< xs) = Just (x, xs)
uncons _ = Nothing

PatternSynonyms भाषा के विस्तार का उपयोग करते हुए, हम पैटर्न को मेल खाने की अनुमति देकर एक समीपवर्ती इंटरफ़ेस दे सकते हैं कि हमारे पास एक कंसोल या स्नोक-सूची है:

{-# LANGUAGE PatternSynonyms #-}
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq

pattern Empty :: Seq a
pattern Empty <- (Seq.viewl -> Seq.EmptyL)

pattern (:<) :: a -> Seq a -> Seq a
pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)

pattern (:>) :: Seq a -> a -> Seq a
pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)

यह हमें बहुत ही प्राकृतिक शैली में uncons लिखने की अनुमति देता है:

uncons :: Seq a -> Maybe (a, Seq a)
uncons (x :< xs) = Just (x, xs)
uncons _ = Nothing

RecordWildCards

RecordWildCards देखें



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow