Haskell Language
सूचियाँ
खोज…
वाक्य - विन्यास
खाली सूची निर्माता
[] :: [a]
गैर-रिक्त सूची निर्माता
(:) :: a -> [a] -> [a]
हेड - किसी सूची का पहला मूल्य लौटाता है
head :: [a] -> a
अंतिम - किसी सूची का अंतिम मान लौटाता है
last :: [a] -> a
पूंछ - पहले आइटम के बिना एक सूची देता है
tail :: [a] -> [a]
init - अंतिम आइटम के बिना एक सूची देता है
init :: [a] -> [a]
xs !! i - सूची xs में तत्व को एक इंडेक्स i पर लौटाते हैं
(!!) :: Int -> [a] -> a
n xs लें - सूची x के पहले तत्वों के n युक्त नई सूची लौटाएँ
take :: Int -> [a] -> [a]
नक्शा :: (a -> b) -> [a] -> [b]
फ़िल्टर :: (a -> बूल) -> [a] -> [a]
(++) :: [a] -> [a]
concat :: [[a]] -> [a]
टिप्पणियों
-
[a]
A[a]
प्रकार[a]
के बराबर[] a
। -
[]
खाली सूची का निर्माण करता है। -
[]
एक फ़ंक्शन परिभाषा में LHS, उदाहरण के लिएf [] = ...
, खाली सूची पैटर्न है। -
x:xs
एक सूची जहां एक तत्व का निर्माणx
सूची के लिए prepended हैxs
-
f (x:xs) = ...
एक गैर-रिक्त सूची के लिए एक पैटर्न मैच है जहांx
सिर है औरxs
पूंछ है। -
f (a:b:cs) = ...
औरf (a:(b:cs)) = ...
समान हैं। वे कम से कम दो तत्वों की सूची के लिए एक पैटर्न मैच हैं जहां पहला तत्वa
, दूसरा तत्वb
, और बाकी सूचीcs
। -
f ((a:as):bs) = ...
f (a:(as:bs)) = ...
। पूर्व सूची के गैर-खाली सूची के लिए एक पैटर्न मैच है, जहांa
सिर का सिर है,as
कि सिर की पूंछ है, औरbs
पूंछ है। -
f (x:[]) = ...
औरf [x] = ...
समान हैं। वे वास्तव में एक तत्व की सूची के लिए एक पैटर्न मैच हैं। -
f (a:b:[]) = ...
औरf [a,b] = ...
समान हैं। वे ठीक दो तत्वों की सूची के लिए एक पैटर्न मैच हैं। -
f [a:b] = ...
वास्तव में एक तत्व की सूची के लिए एक पैटर्न मैच है जहां तत्व भी एक सूची है।a
तत्व का प्रमुख है औरb
तत्व की पूंछ है। -
[a,b,c]
समान है(a:b:c:[])
। मानक सूची संकेतन(:)
और[]
कंस्ट्रक्टर्स के लिए सिंटैक्टिक शुगर है। - आप पूरी सूची को फिर से दोहराने
(x:y:ys)
बजायall
(या कोई अन्य नाम जिसे आप चुनते हैं) को संदर्भित करने के लिएall@(x:y:ys)
का उपयोग कर सकते हैं।
सूची का साहित्य
emptyList = []
singletonList = [0] -- = 0 : []
listOfNums = [1, 2, 3] -- = 1 : 2 : [3]
listOfStrings = ["A", "B", "C"]
सूची का संबंध
listA = [1, 2, 3]
listB = [4, 5, 6]
listAThenB = listA ++ listB -- [1, 2, 3, 4, 5, 6]
(++) xs [] = xs
(++) [] ys = ys
(++) (x:xs) ys = x : (xs ++ ys)
सूची की मूल बातें
हास्केल प्रस्तावना में सूचियों के लिए टाइप कंस्ट्रक्टर []
। प्रकार Int
मानों की सूची रखने वाले प्रकार के लिए घोषणा निम्न प्रकार से लिखी जाती है:
xs :: [Int] -- or equivalently, but less conveniently,
xs :: [] Int
हास्केल में सूचीबद्ध सजातीय क्रम हैं , जो यह कहना है कि सभी तत्व एक ही प्रकार के होने चाहिए। ट्यूपल्स के विपरीत, सूची प्रकार लंबाई से प्रभावित नहीं होता है:
[1,2,3] :: [Int]
[1,2,3,4] :: [Int]
दो कंस्ट्रक्टरों का उपयोग करके सूचियों का निर्माण किया जाता है :
[]
एक खाली सूची का निर्माण करता है।(:)
, उच्चारण "विपक्ष", एक सूची में तत्वों को प्रस्तुत करता है। Consingx
(प्रकार के एक मूल्यa
) परxs
(एक ही प्रकार के मानों की सूचीa
) एक नई सूची, जिनके सिर (पहला तत्व) है बनाता हैx
, और पूंछ (तत्वों के बाकी) हैxs
।
हम सरल सूचियों को निम्नानुसार परिभाषित कर सकते हैं:
ys :: [a]
ys = []
xs :: [Int]
xs = 12 : (99 : (37 : []))
-- or = 12 : 99 : 37 : [] -- ((:) is right-associative)
-- or = [12, 99, 37] -- (syntactic sugar for lists)
ध्यान दें कि (++)
, जिनका उपयोग सूचियों के निर्माण के लिए किया जा सकता है (:)
और []
संदर्भ में पुनरावर्ती रूप से परिभाषित किया गया है।
प्रसंस्करण सूची
सूचियों को संसाधित करने के लिए, हम सूची प्रकार के कंस्ट्रक्टरों पर केवल मिलान कर सकते हैं:
listSum :: [Int] -> Int
listSum [] = 0
listSum (x:xs) = x + listSum xs
हम अधिक विस्तृत पैटर्न निर्दिष्ट करके अधिक मूल्यों का मिलान कर सकते हैं:
sumTwoPer :: [Int] -> Int
sumTwoPer [] = 0
sumTwoPer (x1:x2:xs) = x1 + x2 + sumTwoPer xs
sumTwoPer (x:xs) = x + sumTwoPer xs
ध्यान दें कि उपरोक्त उदाहरण में, हमें उन मामलों को संभालने के लिए अधिक विस्तृत पैटर्न मैच प्रदान करना था जहां एक विषम लंबाई सूची को एक तर्क के रूप में दिया गया है।
हास्केल प्रस्तावना सूची, map
, filter
आदि से निपटने के लिए कई बिल्ट-इन को परिभाषित करता है। जहां संभव हो, आपको अपने स्वयं के पुनरावर्ती कार्यों को लिखने के बजाय इनका उपयोग करना चाहिए।
सूचियों में तत्वों तक पहुँचना
(शून्य आधारित) n एक सूची के वें तत्व एक्सेस करें:
list = [1 .. 10]
firstElement = list !! 0 -- 1
ध्यान दें !!
एक आंशिक कार्य है, इसलिए कुछ इनपुट त्रुटि उत्पन्न करते हैं:
list !! (-1) -- *** Exception: Prelude.!!: negative index
list !! 1000 -- *** Exception: Prelude.!!: index too large
वहाँ भी है Data.List.genericIndex
, का एक अतिभारित संस्करण !!
, जो सूचकांक के रूप में किसी भी Integral
मूल्य को स्वीकार करता है।
import Data.List (genericIndex)
list `genericIndex` 4 -- 5
जब एकल-लिंक्ड सूची के रूप में कार्यान्वित किया जाता है, तो ये ऑपरेशन O (n) समय लेते हैं। यदि आप अनुक्रमणिका द्वारा अक्सर तत्वों का उपयोग करते हैं, तो संभवतः Data.Vector
( वेक्टर पैकेज से) या अन्य डेटा संरचनाओं का उपयोग करना बेहतर होता है।
सीमाओं
श्रेणी संकेतन का उपयोग करके 1 से 10 तक सूची बनाना सरल है:
[1..10] -- [1,2,3,4,5,6,7,8,9,10]
एक चरण निर्दिष्ट करने के लिए, प्रारंभ तत्व के बाद एक अल्पविराम और अगला तत्व जोड़ें:
[1,3..10] -- [1,3,5,7,9]
ध्यान दें कि हास्केल हमेशा शब्दों के बीच अंकगणितीय अंतर के रूप में कदम उठाता है, और यह कि आप पहले दो तत्वों और ऊपरी सीमा से अधिक निर्दिष्ट नहीं कर सकते हैं:
[1,3,5..10] -- error
[1,3,9..20] -- error
अवरोही क्रम में एक श्रेणी उत्पन्न करने के लिए, हमेशा नकारात्मक चरण निर्दिष्ट करें:
[5..1] -- []
[5,4..1] -- [5,4,3,2,1]
क्योंकि हास्केल गैर-सख्त है, सूची के तत्वों का मूल्यांकन केवल अगर वे आवश्यक हैं, जो हमें अनंत सूचियों का उपयोग करने की अनुमति देता है। [1..]
से शुरू होने वाली एक अनंत सूची है। यह सूची एक चर के लिए बाध्य हो सकती है या फ़ंक्शन तर्क के रूप में पारित की जा सकती है:
take 5 [1..] -- returns [1,2,3,4,5] even though [1..] is infinite
फ़्लोटिंग-पॉइंट मानों के साथ श्रेणियों का उपयोग करते समय सावधान रहें, क्योंकि यह गोल मुद्दों से बचने के लिए आधे-डेल्टा तक स्पिल-ओवर स्वीकार करता है:
[1.0,1.5..2.4] -- [1.0,1.5,2.0,2.5] , though 2.5 > 2.4
[1.0,1.1..1.2] -- [1.0,1.1,1.2000000000000002] , though 1.2000000000000002 > 1.2
रंग केवल संख्याओं के साथ नहीं बल्कि किसी भी प्रकार के साथ काम करते हैं जो Enum
टाइपकास्ट को लागू करता है। कुछ गणनीय चर को देखते हुए a
, b
, c
, रेंज वाक्य रचना इन बुला के बराबर है Enum
तरीके:
[a..] == enumFrom a
[a..c] == enumFromTo a c
[a,b..] == enumFromThen a b
[a,b..c] == enumFromThenTo a b c
उदाहरण के लिए, Bool
साथ
[False ..] -- [False,True]
सूचना के बाद अंतरिक्ष False
, यह एक मॉड्यूल का नाम योग्यता के रूप में पार्स किया जा सकता को रोकने के लिए (यानी False..
के रूप में पार्स किया जाएगा .
एक मॉड्यूल से False
)।
सूचियों पर मूल कार्य
head [1..10] -- 1
last [1..20] -- 20
tail [1..5] -- [2, 3, 4, 5]
init [1..5] -- [1, 2, 3, 4]
length [1 .. 10] -- 10
reverse [1 .. 10] -- [10, 9 .. 1]
take 5 [1, 2 .. ] -- [1, 2, 3, 4, 5]
drop 5 [1 .. 10] -- [6, 7, 8, 9, 10]
concat [[1,2], [], [4]] -- [1,2,4]
foldl
इसी तरह से लेफ्ट फोल्ड को लागू किया जाता है। ध्यान दें कि स्टेप फ़ंक्शन में तर्कों का क्रम foldr
(दाएं गुना) की तुलना में foldr
फ़्लिप होता है:
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl f acc [] = acc
foldl f acc (x:xs) = foldl f (f acc x) xs -- = foldl f (acc `f` x) xs
बायाँ फोल्ड, foldl
, एसोसिएट्स को बाईं ओर। अर्थात्:
foldl (+) 0 [1, 2, 3] -- is equivalent to ((0 + 1) + 2) + 3
इसका कारण यह है कि foldl
का मूल्यांकन इस तरह किया जाता है ( foldl
के इंडक्टिव स्टेप को देखें):
foldl (+) 0 [1, 2, 3] -- foldl (+) 0 [ 1, 2, 3 ]
foldl (+) ((+) 0 1) [2, 3] -- foldl (+) (0 + 1) [ 2, 3 ]
foldl (+) ((+) ((+) 0 1) 2) [3] -- foldl (+) ((0 + 1) + 2) [ 3 ]
foldl (+) ((+) ((+) ((+) 0 1) 2) 3) [] -- foldl (+) (((0 + 1) + 2) + 3) []
((+) ((+) ((+) 0 1) 2) 3) -- (((0 + 1) + 2) + 3)
अंतिम पंक्ति ((0 + 1) + 2) + 3
बराबर है। ऐसा इसलिए है क्योंकि (fab)
सामान्य रूप में (a `f` b)
है, और इसलिए ((+) 0 1)
विशेष रूप से (0 + 1)
के समान है।
foldr
यह सही तरीके से लागू किया गया है:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs) -- = x `f` foldr f z xs
दाएं गुना, तह, दाईं ओर foldr
। अर्थात्:
foldr (+) 0 [1, 2, 3] -- is equivalent to 1 + (2 + (3 + 0))
इसका कारण यह है कि foldr
का मूल्यांकन इस तरह किया जाता है ( foldr
के आगमनात्मक कदम को foldr
):
foldr (+) 0 [1, 2, 3] -- foldr (+) 0 [1,2,3]
(+) 1 (foldr (+) 0 [2, 3]) -- 1 + foldr (+) 0 [2,3]
(+) 1 ((+) 2 (foldr (+) 0 [3])) -- 1 + (2 + foldr (+) 0 [3])
(+) 1 ((+) 2 ((+) 3 (foldr (+) 0 []))) -- 1 + (2 + (3 + foldr (+) 0 []))
(+) 1 ((+) 2 ((+) 3 0)) -- 1 + (2 + (3 + 0 ))
अंतिम पंक्ति 1 + (2 + (3 + 0))
बराबर है, क्योंकि ((+) 3 0)
वही है (3 + 0)
।
`मानचित्र` के साथ रूपांतरण
अक्सर हम संग्रह की सामग्री (एक सूची, या कुछ ट्रैवर्सेबल) को परिवर्तित करना या बदलना चाहते हैं। हास्केल में हम map
उपयोग करते हैं:
-- Simple add 1
map (+ 1) [1,2,3]
[2,3,4]
map odd [1,2,3]
[True,False,True]
data Gender = Male | Female deriving Show
data Person = Person String Gender Int deriving Show
-- Extract just the age from a list of people
map (\(Person n g a) -> a) [(Person "Alex" Male 31),(Person "Ellie" Female 29)]
[31,29]
`फ़िल्टर` के साथ फ़िल्टरिंग
एक सूची दी:
li = [1,2,3,4,5]
हम फ़िल्टर का उपयोग करके एक विधेय के साथ एक सूची फ़िल्टर कर सकते हैं filter :: (a -> Bool) -> [a] -> [a]
:
filter (== 1) li -- [1]
filter (even) li -- [2,4]
filter (odd) li -- [1,3,5]
-- Something slightly more complicated
comfy i = notTooLarge && isEven
where
notTooLarge = (i + 1) < 5
isEven = even i
filter comfy li -- [2]
बेशक यह सिर्फ संख्या के बारे में नहीं है:
data Gender = Male | Female deriving Show
data Person = Person String Gender Int deriving Show
onlyLadies :: [Person] -> Person
onlyLadies x = filter isFemale x
where
isFemale (Person _ Female _) = True
isFemale _ = False
onlyLadies [(Person "Alex" Male 31),(Person "Ellie" Female 29)]
-- [Person "Ellie" Female 29]
ज़िपिंग और अनज़िपिंग लिस्ट
ज़िप दो सूची लेता है और संबंधित जोड़े की सूची देता है:
zip [] _ = []
zip _ [] = []
zip (a:as) (b:bs) = (a,b) : zip as bs
> zip [1,3,5] [2,4,6]
> [(1,2),(3,4),(5,6)]
एक फ़ंक्शन के साथ दो सूचियों को ज़िप करना:
zipWith f [] _ = []
zipWith f _ [] = []
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
> zipWith (+) [1,3,5] [2,4,6]
> [3,7,11]
किसी सूची को खोलना:
unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[])
> unzip [(1,2),(3,4),(5,6)]
> ([1,3,5],[2,4,6])