أنماط النشطة (F#)

أنماط النشطة تتيح لك إلى تعريف الأقسام المسماة تقسيم بيانات إدخال، حيث يمكنك استخدام هذه الأسماء في نقش مطابقة التعبير تماما كما تفعل من أجل توحيد discriminated. يمكنك استخدام أنماط النشطة إلى تحلل بيانات بطريقة cusإلىmized لكل قسم.

// Complete active pattern definition.
let (|identifer1|identifier2|...|) [ arguments ] = expression
// Partial active pattern definition.
let (|identifier1|identifier2|...|_|) [ arguments ] = expression

ملاحظات

في بناء الجملة السابق، المعرفات أسماء لأقسام بيانات إدخال التي هو تمثيلها بواسطة arguments، أو، بمعنى آخر، أسماء لمجموعات فرعية المجموعة من قيم الجميع الوسيطات. expressionوصف النموذج في إلى التي إلى تحلل بيانات. يمكنك استخدام تعريف نمط نشط خاص إلى تعريف القواعد الخاصة بتحديد أي من المسمى الأقسام قيم المعطاة كوسيطات تنتمي إلى. (| و |) الرموز هي يشار إليها القصاصات الموز والدالة التي تم إنشاؤها بواسطة th هو النوع من ربط ودع هو يسمى المعرف النشط .

كـ مثال، خذ بعين الاعتبار نقش التالية نشطة مع وسيطة.

let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd

يمكنك استخدام نمط النشطة في نمط المطابقة للتعبير، كـ في المثال التالي.

let TestNumber input =
   match input with
   | Even -> printfn "%d is even" input
   | Odd -> printfn "%d is odd" input

TestNumber 7
TestNumber 11
TestNumber 32

إخراج th هو برنامج هو كما يلي:

7 is odd
11 is odd
32 is even

استخدام أنماط نشط آخر هو تحلل أنواع بيانات بطرق متعددة، مثل عندما يكون نفس بيانات المصدر على تمثيلات الممكنة المختلفة. على سبيل المثال، Colorقد يكون الكائن decomposed تمثيل RGB أو على تمثيل HSB.

open System.Drawing

let (|RGB|) (col : System.Drawing.Color) =
     ( col.R, col.G, col.B )

let (|HSB|) (col : System.Drawing.Color) =
   ( col.GetHue(), col.GetSaturation(), col.GetBrightness() )

let printRGB (col: System.Drawing.Color) =
   match col with
   | RGB(r, g, b) -> printfn " Red: %d Green: %d Blue: %d" r g b

let printHSB (col: System.Drawing.Color) =
   match col with
   | HSB(h, s, b) -> printfn " Hue: %f Saturation: %f Brightness: %f" h s b

let printAll col colorString =
  printfn "%s" colorString
  printRGB col
  printHSB col

printAll Color.Red "Red"
printAll Color.Black "Black"
printAll Color.White "White"
printAll Color.Gray "Gray"
printAll Color.BlanchedAlmond "BlanchedAlmond"

إخراج البرنامج أعلاه كما يلي:

Red
 R: 255 G: 0 B: 0
 H: 0.000000 S: 1.000000 B: 0.500000
Black
 R: 0 G: 0 B: 0
 H: 0.000000 S: 0.000000 B: 0.000000
White
 R: 255 G: 255 B: 255
 H: 0.000000 S: 0.000000 B: 1.000000
Gray
 R: 128 G: 128 B: 128
 H: 0.000000 S: 0.000000 B: 0.501961
BlanchedAlmond
 R: 255 G: 235 B: 205
 H: 36.000000 S: 1.000000 B: 0.901961

في تركيبة، هاتين الطريقتين من استخدام أنماط النشطة تتيح لك إلى القسم وتحلل بيانات إلى النموذج المناسب فقط وإجراء حسابات المناسبة تشغيل بيانات المناسبة الموجودة في النموذج الأكثر ملاءمة للحساب.

النمط الناتج تطابق بيانات تمكين التعبيرات المراد كتابتها في المنطق ملائمة مقروءة طريقة هو، إلى حد كبير simplifying المعقدة التي قد تكون التفريعي وتحليل بيانات تعليمات برمجية.

أنماط نشط Directory جزئي

في بعض الأحيان، أنت بحاجة إلى تقسيم جزء فقط من مسافة إدخال. في هذه الحالة، كتابة التعيين من النقوش جزئي من أي تطابق بعض الإدخالات ولكن فشل لمطابقة غير ذلك الإدخالات. تدعي الأنماط النشطة لا تنتج دائماً القيمة الأنماط النشطة الجزئية ؛ وإرجاع الالقيمة التي يكون لها هو على نوع خيار. إلى تعريف نقش نشطة جزئية، استخدم حرف بدل (_) في إنهاء قائمة أنماط داخل المقاطع الموز. يلي تعليمات برمجية يوضح استخدام نمط النشطة الجزئي.

let (|Integer|_|) (str: string) =
   let mutable intvalue = 0
   if System.Int32.TryParse(str, &intvalue) then Some(intvalue)
   else None

let (|Float|_|) (str: string) =
   let mutable floatvalue = 0.0
   if System.Double.TryParse(str, &floatvalue) then Some(floatvalue)
   else None

let parseNumeric str =
   match str with
     | Integer i -> printfn "%d : Integer" i
     | Float f -> printfn "%f : Floating point" f
     | _ -> printfn "%s : Not matched." str

parseNumeric "1.1"
parseNumeric "0"
parseNumeric "0.0"
parseNumeric "10"
parseNumeric "Something else"

إخراج المثال السابق هو كما يلي:

1.100000 : Floating point
0 : Integer
0.000000 : Floating point
10 : Integer
Something else : Not matched.

عند استخدام النشطة جزئي أنماط، في بعض الأحيان يمكن الاختيارات الفردية تبادلية أو منفصلة، ولكنها تحتاج إلى لا. في المثال التالي، في مربع نقش ونمط مكعب غير منفصلة، لأن بعض الأرقام كل من المربعات والمكعبات، مثل كـ 64. يطبع البرنامج التالي عن الجميع الأرقام الصحيحة حتى إلى 1000000 المربعات والمكعبات.

let err = 1.e-10

let floatequal x y =
   abs (x - y) < err

let (|Square|_|) (x : int) =
  if floatequal (sqrt (float x)) (round (sqrt (float x))) then Some(x)
  else None

let (|Cube|_|) (x : int) =
  if floatequal ((float x) ** ( 1.0 / 3.0)) (round ((float x) ** (1.0 / 3.0))) then Some(x)
  else None

let examineNumber x =
   match x with
      | Cube x -> printfn "%d is a cube" x
      | _ -> ()
   match x with
      | Square x -> printfn "%d is a square" x
      | _ -> ()

let findSquareCubes x =
   if (match x with
       | Cube x -> true
       | _ -> false
       &&
       match x with
       | Square x -> true
       | _ -> false
      )
   then printf "%d \n" x

الإخراج هو كما يلي:

1
64
729
4096
15625
46656
117649
262144
531441
1000000

أنماط نشط Directory ذات معلمات

أنماط نشطة دائماً أخذ في leكـt وسيطة واحدة للعنصر الذي يتم مطابقة، ولكن قد تصبح وسائط إضافى كـ أيضا، في cكـe أي نقش النشطة معلمات اسم تطبيق. وسائط إضافى تسمح نقش عامة إلى تكون التخصصية. نقوش النشطة على سبيل المثال، تستخدم تعابير عادية إلى سلاسل التوزيع غالباً ما تضمين تعبير عادي كمعلمة إضافية، كما في التعليمة البرمجية التالية، والذي يستخدم أيضا في نقش النشطة الجزئية Integerالمعرفة في السابقة رمز المثال. في هذا المثال، يتم إعطاء سلاسل إعطاء التعابير النظامية للعديد من تنسيقات التاريخ إلى cusإلىmize نقش النشطة ParseRegex عام. نقش النشط لعدد صحيح هو المستخدمة لتحويل سلاسل متطابقة إلى الإعداد الصحيحة التي يمكن تمرير الدالة الإنشائية التاريخ والوقت.

open System.Text.RegularExpressions

// ParseRegex parses a regular expression and returns a list of the strings that match each group in
// the regular expression.
// List.tail is called to eliminate the first element in the list, which is the full matched expression,
// since only the matches for each group are wanted.
let (|ParseRegex|_|) regex str =
   let m = Regex(regex).Match(str)
   if m.Success
   then Some (List.tail [ for x in m.Groups -> x.Value ])
   else None

// Three different date formats are demonstrated here. The first matches two-
// digit dates and the second matches full dates. This code assumes that if a two-digit
// date is provided, it is an abbreviation, not a year in the first century.
let parseDate str =
   match str with
     | ParseRegex "(\d{1,2})/(\d{1,2})/(\d{1,2})$" [Integer m; Integer d; Integer y]
          -> new System.DateTime(y + 2000, m, d)
     | ParseRegex "(\d{1,2})/(\d{1,2})/(\d{3,4})" [Integer m; Integer d; Integer y]
          -> new System.DateTime(y, m, d)
     | ParseRegex "(\d{1,4})-(\d{1,2})-(\d{1,2})" [Integer y; Integer m; Integer d]
          -> new System.DateTime(y, m, d)
     | _ -> new System.DateTime()

let dt1 = parseDate "12/22/08"
let dt2 = parseDate "1/1/2009"
let dt3 = parseDate "2008-1-15"
let dt4 = parseDate "1995-12-28"

printfn "%s %s %s %s" (dt1.ToString()) (dt2.ToString()) (dt3.ToString()) (dt4.ToString())

يكون الإخراج من تعليمات برمجية السابق كـ التالي:

12/22/2008 12:00:00 AM 1/1/2009 12:00:00 AM 1/15/2008 12:00:00 AM 12/28/1995 12:00:00 AM

راجع أيضًا:

المرجع

تطابق التعبيرات (F#)

موارد أخرى

مرجع لغة ب #