Etkin desenleri (F#)
Etkin desenleri discriminated sendika için yaptığınız gibi ifade eşleştirme deseninde bu adlar kullanın böylece giriş verileri alt bölümlere adlandırılmış bölümler tanımlamak olanak sağlar. Yönetilebilen ve her bölümiçin özelleştirilmiş bir şekilde veri dağıtılabilen için etkin desenler kullanabilirsiniz.
// Complete active pattern definition.
let (|identifer1|identifier2|...|) [ arguments ] = expression
// Partial active pattern definition.
let (|identifier|_|) [ arguments ] = expression
Notlar
Önceki sözdiziminde tanımlayıcıları tarafından temsil edilen giriş veri bölümlerinin adları olan arguments, veya başka bir deyişle, bağımsız değişkenlerinin tüm değerler kümesinin alt kümeleri için adları. Etkin desen tanımı içinde en çok yedi bölüm olabilir. expression form , veri yönetilebilen ve dağıtılabilen açıklar. Etkin desen tanımı, adlandırılmış bölümler ait bağımsız değişkenler olarak verilen değerleri belirlenmesi için kurallar tanımlamak için kullanabilirsiniz. (| Ve |) sembolleri olarak anılacaktır banana klipleri ve bu tür organizayonunuzdaki bağlantı tarafından oluşturulan işlev adı verilen bir etkin tanıyıcı.
Örneğin, bağımsız değişkenaşağıdaki active desenle düşünün.
let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd
Aşağıdaki örnekte olduğu gibi ifade eşleştirme deseninde etkin desen kullanabilirsiniz.
let TestNumber input =
match input with
| Even -> printfn "%d is even" input
| Odd -> printfn "%d is odd" input
TestNumber 7
TestNumber 11
TestNumber 32
Bu program çıktısı şöyledir:
7 is odd
11 is odd
32 is even
Başka bir etkin desenleri veri türleri aynı temel verileri çeşitli olası gösterimler olduğunda gibi birden çok yolla yönetilebilen ve dağıtılabilen için kullanılır. Örneğin, bir Color nesne decomposed rgb temsili veya hsb gösterimi.
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"
Yukarıdaki program çıktısı aşağıdaki gibidir:
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
Birlikte, etkin örüntüsü kullanarak bu iki yolu bölüm etkinleştirmek ve verileri yalnızca uygun form yönetilebilen ve dağıtılabilen ve uygun verileri form hesaplaması için en uygun uygun hesaplamaları gerçekleştirmek.
Elde edilen desen eşleştirme deyimleri verilerin büyük ölçüde potansiyel olarak karmaşık dallanma ve veri çözümleme kodu basitleştirecek çok okunabilir rahat bir şekilde yazılmasına olanak verir.
Kısmi etkin desenleri
Bazen, bölüm giriş alanının yalnızca bir kısmı gerekir. Bu durumda, bazı girişleri eşleşmesi ancak diğer girdileri eşleşecek şekilde başarısız her kısmi desenler bir dizi yazma. Her zaman bir değer üretmez etkin desenleri verilir kısmi etkin desenleri; sahip oldukları bir seçenek türü olan bir dönüş değeri. kısmi bir etkin deseni tanımlamak için banana klipleri içini desenleri listesi sonunda bir joker karakter (_) kullanın. Aşağıdaki kod, kısmi etkin desen kullanımını göstermektedir.
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"
Önceki örnekteki çıktısı aşağıdaki gibidir:
1.100000 : Floating point
0 : Integer
0.000000 : Floating point
10 : Integer
Something else : Not matched.
kısmi etkin desenleri kullanırken, bazen bireysel seçimler ayrık veya dışlayan olabilir, ancak bunların olmaması. Bazı kareler hem de 64 gibi küpleri olduğundan aşağıdaki örnekte desen kare ve küp desen ayrık, değildir. Aşağıdaki program bütün tamsayılar dışında en çok, kareler ve küplerini 1000000 yazdırır.
let err = 1.e-10
let isNearlyIntegral (x:float) = abs (x - round(x)) < err
let (|Square|_|) (x : int) =
if isNearlyIntegral (sqrt (float x)) then Some(x)
else None
let (|Cube|_|) (x : int) =
if isNearlyIntegral ((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 .. 1000000 ] |> List.iter (fun elem -> findSquareCubes elem)
Çıktı aşağıdaki gibidir:
1
64
729
4096
15625
46656
117649
262144
531441
1000000
Parametreli etkin desenleri
Etkin desenleri eşleşen öğe için en az bir bağımsız değişken her zaman alabilir, ancak adı durumda ek bağımsız değişkenler aynı zamanda sürebilir parametreli etkin desen uygulanır. Ek bağımsız değişkenler özelleştirilmesi genel bir desene izin verir. Örneğin, fazladan bir parametreolarak da kısmi etkin desen kullanan aşağıdaki kodda, olarak normal ifade dizeleri genellikle ayrıştırmak için normal ifadeleri kullanan active desenleri dahil Integer önceki kod örneğinde tanımlanan. Bu örnekte, çeşitli tarih biçimleri için normal ifadeleri kullanan dizeleri özelleştirmek için genel ParseRegex etkin desen verilir. Tamsayı etkin desen dönüştürmek eşleşen dizelerin DateTime oluşturucugeçirilen tamsayılar kullanılan..
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())
Önceki kod çıktısı aşağıdaki gibidir:
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