खोज…
सिलवटों के लिए, उदाहरण के एक मुट्ठी भर के साथ
सिलवटों (उच्च-क्रम) कार्य तत्वों के अनुक्रम के साथ उपयोग किए जाते हैं। वे seq<'a>
को 'b
जहाँ 'b
किसी भी प्रकार (संभवतः अभी भी 'a
) है। यह थोड़ा अमूर्त है जिससे ठोस व्यावहारिक उदाहरण मिलते हैं।
सभी संख्याओं के योग की गणना
इस उदाहरण में, 'a
एक int
। हमारे पास संख्याओं की एक सूची है और हम इसकी सभी संख्याओं की गणना करना चाहते हैं। सूची की संख्या का योग करने के लिए [1; 2; 3]
हम लिखते हैं
List.fold (fun x y -> x + y) 0 [1; 2; 3] // val it : int = 6
मुझे समझाएं, क्योंकि हम सूचियों के साथ काम कर रहे हैं, हम List
मॉड्यूल में fold
का उपयोग करते हैं, इसलिए List.fold
। पहला तर्क fold
एक बाइनरी फ़ंक्शन है, फ़ोल्डर । दूसरा तर्क प्रारंभिक मूल्य है । fold
शुरू होता है लगातार सूची में तत्वों प्रारंभिक मूल्य और पहला तत्व के साथ शुरू करने के लिए फ़ोल्डर समारोह लगाने से सूची तह। यदि सूची रिक्त है, तो इनबिल्ट मान लौटा दिया जाता है!
निष्पादन उदाहरण का योजनाबद्ध अवलोकन इस प्रकार है:
let add x y = x + y // this is our folder (a binary function, takes two arguments)
List.fold add 0 [1; 2; 3;]
=> List.fold add (add 0 1) [2; 3]
// the binary function is passed again as the folder in the first argument
// the initial value is updated to add 0 1 = 1 in the second argument
// the tail of the list (all elements except the first one) is passed in the third argument
// it becomes this:
List.fold add 1 [2; 3]
// Repeat untill the list is empty -> then return the "inital" value
List.fold add (add 1 2) [3]
List.fold add 3 [3] // add 1 2 = 3
List.fold add (add 3 3) []
List.fold add 6 [] // the list is empty now -> return 6
6
समारोह List.sum
मोटे तौर पर List.fold add LanguagePrimitives.GenericZero
जहां सामान्य शून्य इसे पूर्णांक, फ़्लोट्स, बड़े पूर्णांक आदि के साथ संगत बनाता है।
एक सूची में गिनती हाथी (कार्यान्वयन count
)
यह ऊपर के रूप में लगभग समान ही किया जाता है, लेकिन सूची में तत्व के वास्तविक मूल्य की अनदेखी करके और इसके बजाय 1 को जोड़ना।
List.fold (fun x y -> x + 1) 0 [1; 2; 3] // val it : int = 3
इसे इस तरह भी किया जा सकता है:
[1; 2; 3]
|> List.map (fun x -> 1) // turn every elemet into 1, [1; 2; 3] becomes [1; 1; 1]
|> List.sum // sum [1; 1; 1] is 3
इसलिए आप count
को निम्नानुसार परिभाषित कर सकते हैं:
let count xs =
xs
|> List.map (fun x -> 1)
|> List.fold (+) 0 // or List.sum
अधिकतम सूची प्राप्त करना
इस बार हम का उपयोग करेगा List.reduce
जो की तरह है List.fold
लेकिन इस मामले में हम किस प्रकार मूल्यों हम compairing कर रहे हैं की वह जगह है जहाँ पता नहीं है के रूप में एक प्रारंभिक मूल्य के बिना:
let max x y = if x > y then x else y
// val max : x:'a -> y: 'a -> 'a when 'a : comparison, so only for types that we can compare
List.reduce max [1; 2; 3; 4; 5] // 5
List.reduce max ["a"; "b"; "c"] // "c", because "c" > "b" > "a"
List.reduce max [true; false] // true, because true > false
एक सूची के न्यूनतम ढूँढना
जैसे अधिकतम खोजने पर, फ़ोल्डर अलग होता है
let min x y = if x < y then x else y
List.reduce min [1; 2; 3; 4; 5] // 1
List.reduce min ["a"; "b"; "c"] // "a"
List.reduce min [true; false] // false
संबंधित सूची
यहां हम सूचियों की सूची ले रहे हैं फ़ोल्डर फ़ंक्शन @
ऑपरेटर है
// [1;2] @ [3; 4] = [1; 2; 3; 4]
let merge xs ys = xs @ ys
List.fold merge [] [[1;2;3]; [4;5;6]; [7;8;9]] // [1;2;3;4;5;6;7;8;9]
या आप अपने फ़ोल्डर फ़ंक्शन के रूप में बाइनरी ऑपरेटरों का उपयोग कर सकते हैं:
List.fold (@) [] [[1;2;3]; [4;5;6]; [7;8;9]] // [1;2;3;4;5;6;7;8;9]
List.fold (+) 0 [1; 2; 3] // 6
List.fold (||) false [true; false] // true, more on this below
List.fold (&&) true [true; false] // false, more on this below
// etc...
किसी संख्या के भाज्य की गणना करना
समान विचार जब संख्याओं को जोड़ते हैं, लेकिन अब हम उन्हें गुणा करते हैं। अगर हम चाहते हैं कि n
स्थलीय सूची में हम सभी तत्वों को गुणा करें [1 .. n]
। कोड बन जाता है:
// the folder
let times x y = x * y
let factorial n = List.fold times 1 [1 .. n]
// Or maybe for big integers
let factorial n = List.fold times 1I [1I .. n]
को लागू करने forall
, exists
और contains
फ़ंक्शन forall
जाँच करता है कि क्या सभी अनुक्रम एक स्थिति को संतुष्ट करते हैं। exists
जाँचता है कि सूची में एक तत्व स्थिति को संतुष्ट करता है या नहीं। पहले हमें यह जानने की जरूरत है कि bool
मूल्यों की सूची को कैसे ध्वस्त किया जाए। खैर, हम तह की तह का उपयोग करते हैं! बूलियन ऑपरेटर हमारे फ़ोल्डर फ़ंक्शन होंगे।
यह जांचने के लिए एक सूची में सभी तत्व हैं true
हम उनके साथ पतन &&
साथ समारोह true
प्रारंभिक मूल्य के रूप में।
List.fold (&&) true [true; true; true] // true
List.fold (&&) true [] // true, empty list -> return inital value
List.fold (&&) true [false; true] // false
इसी तरह, यह जाँचने के लिए कि क्या एक सूची बूलियन्स में एक तत्व true
, हम इसे ||
प्रारंभिक मूल्य के रूप में false
साथ ऑपरेटर:
List.fold (||) false [true; false] // true
List.fold (||) false [false; false] // false, all are false, no element is true
List.fold (||) false [] // false, empty list -> return inital value
वापस forall
और exists
। यहां हम किसी भी प्रकार की एक सूची लेते हैं, सभी तत्वों को बूलियन मूल्यों में बदलने के लिए स्थिति का उपयोग करते हैं और फिर हम इसे नीचे गिरते हैं:
let forall condition elements =
elements
|> List.map condition // condition : 'a -> bool
|> List.fold (&&) true
let exists condition elements =
elements
|> List.map condition
|> List.fold (||) false
यह जांचने के लिए कि क्या सभी तत्व [1]; 2; 3; 4] 5 से छोटे हैं:
forall (fun n -> n < 5) [1 .. 4] // true
exists
पद्धति को परिभाषित करें contains
exists
:
let contains x xs = exists (fun y -> y = x) xs
या और भी
let contains x xs = exists ((=) x) xs
अब जांचें कि क्या सूची [1 .. 5] में मान 2 है:
contains 2 [1..5] // true
reverse
लागू करना:
let reverse xs = List.fold (fun acc x -> x :: acc) [] xs
reverse [1 .. 5] // [5; 4; 3; 2; 1]
map
और filter
लागू करना
let map f = List.fold (fun acc x -> List.append acc [f x]) List.empty
// map (fun x -> x * x) [1..5] -> [1; 4; 9; 16; 25]
let filter p = Seq.fold (fun acc x -> seq { yield! acc; if p(x) then yield x }) Seq.empty
// filter (fun x -> x % 2 = 0) [1..10] -> [2; 4; 6; 8; 10]
वहाँ कुछ भी नहीं कर सकते fold
है? मुझे नहीं पता
किसी सूची के सभी तत्वों के योग की गणना
किसी संख्या सूची के शब्दों (प्रकार फ़्लोट, इंट या बड़ा पूर्णांक) की राशि की गणना करने के लिए, List.sum का उपयोग करना बेहतर होता है। अन्य मामलों में, List.fold वह फ़ंक्शन है जो ऐसी राशि की गणना करने के लिए सबसे उपयुक्त है।
- जटिल संख्याओं का योग
इस उदाहरण में, हम जटिल संख्याओं की एक सूची घोषित करते हैं और हम सूची में सभी शर्तों के योग की गणना करते हैं।
कार्यक्रम की शुरुआत में, System.Numerics का संदर्भ जोड़ें
ओपन सिस्टम। न्यूमेरिक्स
राशि की गणना करने के लिए, हम संचयक को जटिल संख्या 0 से आरंभ करते हैं।
let clist = [new Complex(1.0, 52.0); new Complex(2.0, -2.0); new Complex(0.0, 1.0)]
let sum = List.fold (+) (new Complex(0.0, 0.0)) clist
परिणाम:
(3, 51)
- संघ प्रकार की संख्याओं का योग
मान लीजिए कि एक सूची यूनियन (फ्लोट या इंट) प्रकार की संख्याओं से बनी होती है और इन संख्याओं के योग की गणना करना चाहती है।
निम्नलिखित संख्या प्रकार से पहले घोषणा करें:
type number =
| Float of float
| Int of int
किसी सूची के प्रकार की संख्या के योग की गणना करें:
let list = [Float(1.3); Int(2); Float(10.2)]
let sum = List.fold (
fun acc elem ->
match elem with
| Float(elem) -> acc + elem
| Int(elem) -> acc + float(elem)
) 0.0 list
परिणाम:
13.5
फ़ंक्शन का पहला पैरामीटर, जो संचयकर्ता का प्रतिनिधित्व करता है, प्रकार फ़्लोट का है और दूसरा पैरामीटर, जो सूची में एक आइटम का प्रतिनिधित्व करता है प्रकार संख्या का है। लेकिन इससे पहले कि हम जोड़ते हैं, हमें पैटर्न का उपयोग करने की आवश्यकता होती है और फ्लोट टाइप करने के लिए डाली जाती है जब एलएम टाइप का होता है।