F # 6: Tuples

لذلك ، تستمر رحلتنا إلى F #. ستركز المقالة التالية على أنواع F # التي قد تحتوي أو لا تحتوي على معادلات .NET قياسية. هذا المنصب هو عن tuples.

ما هي tuples


tuple هي مجموعة من القيم غير المسماة لكن المرتبة ، ربما من أنواع مختلفة.

خلق Tuples


من السهل جدًا إنشاء Tuples ، فنحن نفعل شيئًا مثل الشيء الموضح أدناه. لاحظ كيف أنشأت حزمة مختلطة من tuples ، بعضها أرقام وأخرى سلاسل ، ويمكننا أيضًا مزج أنواع القيم وعددها ومطابقتها.

let a = (1,2) let b = (1,"cat") let c = (1,"cat") let d = (1,"cat", 'c') 

tuples العالمي


يمكن أن تقبل الوظائف التي تقبل tuples أيضًا tuples العالمية دون أي مشاكل. نظام الاستدلال مثل F # سوف يتعامل بسعادة مع استنتاج الأنواع الصحيحة للترابل. هنا مثال.

 let someFunction tup = let (x,y) = tup printfn "x is %A and y is %A" xy do someFunction ("cat","dog") do someFunction (11,12) 

وإليكم نتائج التنفيذ أعلاه ، حيث يمكنك أن ترى أن وظيفة someFunction قد قبلت وعملت مع مختلف tuples المكتوبة دون مشاكل.

صورة

تواقيع التواقيع


حتى الآن ، لم نتطرق إلى فهم تواقيع F # على الإطلاق ، في الواقع ، هذا موضوع قررت أيضًا تكريسه لنشر مدونة كاملة ، لأنني أعتقد أنها معقدة للغاية. ومع ذلك ، نحن موجودون في مكاننا ، أي هنا والآن ، ونحن ندرس التلاميذ ، لذلك الآن أردت فقط أن أظهر الشكل الذي سيبدو عليه التوقيع.

لنفترض أنني أعلنت عن عدد الطلاب التاليين في نافذة FSI:
 let a = (1,2) let b = (1,"codfather") let c = (1,"c", 12.5) 

ثم درستهم في نافذة FSI ؛ سوف نرى شيء مثل هذا:
 val a : int * int = (1, 2) val b : int * string = (1, "codfather") val c : int * string * float = (1, "c", 12.5) 

هذا مثير للاهتمام ، يمكننا أن نرى بعض الأشياء هنا ، وهي:
  • الأقواس ليست جزءًا من توقيع الكتابة
  • يمكن لنظام نوع F # أن يستنتج نوعًا صحيحًا استنادًا إلى القيم الموجودة في المجموعة نفسها.
  • يتم استبدال الفاصلة بـ "*"

لذا فإن الطبقة الشفافة الصافية تبدو كالتالي:
 let a = (1,2) 

سوف يكون التوقيع التالي:
 int * int 


انهيار Tuple


لذلك ، رأينا كيف يمكننا إنشاء tuples ، ولكن ماذا عن تقسيمهم أو فكهم إلى قيم منفصلة. هل هذا ممكن؟ نعم بالطبع. كما كان من قبل ، لنبدأ ببعض الأمثلة:
 let (a,b) = (1,2) printfn "(a,b) = (1,2), so value of 'a' should be 1, and it is =%i,\r\n 'b' should be 2, and it is =%i" ab //   ,  ,     ,   //     let (_,z) = (1,2) printfn "grabbing last value from (1,2) which is = %i" z let (a,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a :int,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a ,b, c) = (1,"cat", 'c') printfn "grabbing (1,\"cat\",'c') which has values = %i %s %c" abc let first = fst (1, 2) printfn "grabbing fst from (1,2) which has values = %i" first let second = snd (1, 2) printfn "grabbing 2nd from (1,2) which has values = %i" second 

تتم طباعة النتائج في نافذة وحدة التحكم القياسية ، على النحو التالي:
صورة

باستخدام Let


ولكن كيف حصلنا على الأجزاء الفردية؟ حسنًا ، كل ما تحتاجه هو الكود أعلاه ، ولكن دعونا نلقي نظرة على مثال واحد. لنفترض أن لدينا مجموعة مثل هذه:
 (1,2) 

وأردت الحصول على قيم "قيم" القيمتين المرتبطتين ببعض القيم الفردية الجديدة ، يمكننا القيام بذلك فقط:
 let (a,b) = (1,2) 

يمكننا أيضًا تحديد فقط تلك القيم التي نحتاجها حقًا ، والتي تتم باستخدام أحرف البدل للأجزاء غير المرغوب فيها. مما يضمن عدم وجود قيمة غير ضرورية ملزمة. هنا مثال:
 let (_,z) = (1,2) 


باستخدام وظائف tuple المضمنة


يوجد أيضًا دعم مدمج للحصول على القيمتين الأولى والثانية من tuple. ما الذي يمكن عمله باستخدام الدالتين " fst " و " snd ". لا يوجد دعم لأي شيء غير العنصر الثاني (ربما تكون هذه الحالات الأكثر شيوعًا). يمكن استخدام " Fst " و " snd " على النحو التالي:
 let first = fst (1, 2) let second = snd (1, 2) 

الآن أود أن ألفت انتباهكم إلى حالة خاصة حيث قد يكون لدينا عدم تطابق مع عدد القيم التي نحاول أن تنفجر في القيم الفردية. لذلك سيكون هذا مثالاً على ذلك هنا:
 let (a ,b) = (1,"cat", 'c') 

يمكنك أن ترى أن المجموعة نفسها تحتوي فعليًا على 3 قيم ، ولكن الرابط Let يحتوي على قيمتين فقط ، لذا يحذرنا المترجم من ذلك ، كما ترى في لقطة الشاشة أدناه:
صورة

خلق Tuples جديدة


قد ترغب في إنشاء مجموعات جديدة من المجموعات الموجودة ، إنها بسيطة بما فيه الكفاية ، فيما يلي مثال على ذلك:
 let oldOne = (1,2) let (x,y) = oldOne let newOne = (x+1,y+1) printfn "original = %A, and we did this (x+1,y+1)\r\n to obtain newOne = %A" oldOne newOne 

صورة

مقارنة tuples


Tuples تعتبر متساوية فقط إذا

  • لديهم نفس عدد القيم.
  • تعتبر جميع القيم متساوية (من الواضح أن هذه يمكن أن تكون طرق Equals مخصصة أو تطبيقات IEquatable مخصصة وما شابه ذلك)

دعنا ننظر إلى بعض الأمثلة البسيطة.

 printfn "(1,2) = (3,4) =% b" ((1,2) = (3,4)) printfn "(1,2) = (1,2) =% b" ((1,2) = (1,2)) printfn "('a', 'b') = ('a', 'b') =% b" (('a', 'b') = ('a', 'b')) printfn "('a', 'b') = ('a', 'c') =% b" (('a', 'b') = ('a', 'c')) 

صورة

في الواقع ، إذا كان لدى تلاميذك أطوال مختلفة (عدد العناصر) وحاولت مقارنتها باستخدام معامل المساواة "=" ، فستتلقى تحذيرًا:
صورة

أنماط مطابقة Tuple


لم نتعامل مع أنماط مطابقة بعد ، ولكننا سنرى لاحقًا منشورًا كاملاً حول هذا الموضوع. في غضون ذلك ، تعرف فقط أن هذه طريقة لمطابقة معلمات الإدخال مرة أخرى. يمكنك القيام بذلك من أجل tuples ، والذي يتم على النحو التالي:
 let someFunction tup = match tup with | 1,2 -> printfn "you passed (1,2)" | _,_ -> printfn "you passed some other tuple" do someFunction (11,12) do someFunction (4,5) do someFunction (1,2) do someFunction (13,23) 

صورة

Source: https://habr.com/ru/post/ar470271/


All Articles