أنواع مرونة (F#)
على مرونة نوع التعليق التوضيحي إلى أن معلمة أو متغير القيمة به نوع متوافق مع نوع المحدد، الموقع يتم تحديد توافق حسب الموضع في التسلسل هرمي لموجهة إلى كائن من الفئات أو واجهات. Flexible أنواع are useful specifically when the تلقائي تحويل إلى أنواع higher في the نوع هيكلي does not occur but you still want إلى تمكين your functionality إلى work مع أي نوع في the هيكلي أو أي نوع that implements an واجهة.
#type
ملاحظات
في the السابق بناء الجملة, type represents a الأساس نوع أو an واجهة.
A flexible نوع هو equivalent إلى a generic نوع that has a قيد that limits the allowed أنواع إلى أنواع that are متوافق مع the الأساس أو واجهة نوع. That هو, the following الثاني lines of تعليمات برمجية are equivalent.
#SomeType
'a when 'a :> SomeType
Flexible أنواع are useful في several أنواع of situations. For مثال, when you have a higher ترتيب دالة (a دالة that takes a دالة كـ an وسيطة), it هو often useful إلى have the دالة return a flexible نوع. في the following مثال, the استخدم of a flexible نوع مع a تسلسلات وسيطة في iterate2 enables the higher ترتيب دالة إلى work مع دالات that توليد تسلسلات, arrays, lists, و أي غير ذلك قابل للتعداد نوع.
Consider the following الثاني دالات, واحد of which إرجاع a تسلسل, the غير ذلك of which إرجاع a flexible نوع.
let iterate1 (f : unit -> seq<int>) =
for e in f() do printfn "%d" e
let iterate2 (f : unit -> #seq<int>) =
for e in f() do printfn "%d" e
// Passing a function that takes a list requires a cast.
iterate1 (fun () -> [1] :> seq<int>)
// Passing a function that takes a list to the version that species a
// flexible type as the return value is OK as is.
iterate2 (fun () -> [1])
كـ another مثال, consider the Seq.concat مكتبة دالة:
val concat: sequences:seq<#seq<'T>> -> seq<'T>
You can pass أي of the following قابل للتعداد تسلسلات إلى this دالة:
A قائمة of lists
A قائمة of arrays
صفيفة القوائم
An مصفوفه من تسلسلات
أي غير ذلك combination of قابل للتعداد تسلسلات
The following تعليمات برمجية uses Seq.concat إلى demonstrate the scenarios that you can دعم بواسطة using flexible أنواع.
let list1 = [1;2;3]
let list2 = [4;5;6]
let list3 = [7;8;9]
let concat1 = Seq.concat [ list1; list2; list3]
printfn "%A" concat1
let array1 = [|1;2;3|]
let array2 = [|4;5;6|]
let array3 = [|7;8;9|]
let concat2 = Seq.concat [ array1; array2; array3 ]
printfn "%A" concat2
let concat3 = Seq.concat [| list1; list2; list3 |]
printfn "%A" concat3
let concat4 = Seq.concat [| array1; array2; array3 |]
printfn "%A" concat4
let seq1 = { 1 .. 3 }
let seq2 = { 4 .. 6 }
let seq3 = { 7 .. 9 }
let concat5 = Seq.concat [| seq1; seq2; seq3 |]
printfn "%A" concat5
الإخراج هو كما يلي.
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
seq [1; 2; 3; 4; ...]
F#, كما في لغات غير ذلك مبنية على الكائن، يوجد في السياقات التي هي الأنواع المشتقة أو أنواع واجهات تطبيق محول auإلىmatically إلى النوع الأساسي أو نوع الواجهة. تحدث هذه التحويلات تلقائي في الوسيطات المباشرة، ولكن ليس عند النوع هو في موضع الثانوية، كجزء من نوع أكثر تعقيداً مثل نوع إرجاع من نوع دالة، أو كوسيطة نوع. منهج النوع مرنة وهكذا، هو أساسا مفيداً عند النوع عند تطبيق حتى هو جزءا من نوع أكثر تعقيداً.