Sdílet prostřednictvím


Aktivní vzorky (F#)

Vzorky Active umožňují definovat pojmenovanou oddíly, které rozdělit vstupní data tak, aby tyto názvy můžete použít vzorek odpovídající výraz, stejně jako pro discriminated unie.Aktivní vzorky lze rozložit data pro každý oddílvlastní způsobem.

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

Poznámky

V syntaxi předchozí identifikátory jsou názvy oddílů vstupních dat, který je reprezentován arguments, nebo jinými slovy, názvy pro dílčí sadu všech hodnot argumentů.V definici aktivní vzorek může být až sedm oddíly.expression Popisuje formulář , do kterého rozložit data.Můžete definovat pravidla pro určování oddílů pojmenované hodnoty jako argumenty patří k definici aktivní vzorek.(| A |) symboly jsou označovány jako banánů klipy a vytvořil tento typ vazby umožňují funkce je volána aktivní rozpoznávání.

Například zvažte následující aktivní vzorek s argument.

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

Aktivní vzor můžete použít v porovnávání výraz, jako v následujícím příkladu.

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

TestNumber 7
TestNumber 11
TestNumber 32

Výstup program je následující:

7 is odd
11 is odd
32 is even

Jiné vzorky aktivní slouží rozložit datové typy několika způsoby, například pokud má stejné podkladová data různých možných zastoupení.Například Color objekt nelze rozložit na reprezentaci RGB nebo reprezentaci 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"

Výstup výše uvedeného program je následující:

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

V kombinaci tyto dva způsoby použití aktivní vzorky umožňují oddíl a data rozloží příslušný formulář a provádět příslušné výpočty na příslušná data formulář nejvýhodnější výpočtu.

Výsledný vzorek odpovídající výrazy povolit zápis vhodným způsobem, který je velmi čitelný, výrazně zjednodušit potenciálně složité větvení a kód analýza dat dat.

Dílčí vzorky aktivní

Někdy potřebujete pouze část vstupní místa oddíl .V takovém případě sadu částečný kód vzorky zapsat které odpovídají některé vstupy, ale selhání odpovídající další vstupy.Aktivní vzorky, které neposkytují vždy hodnotu, se nazývají částečný kód vzorky active; Vrácená hodnota, která je typ možnosti mají.Chcete-li definovat částečný kód vzorek aktivní použijte zástupný znak (_) na konci seznamu vzorek uvnitř klipů banánů.Následující kód ilustruje použití částečný kód aktivní vzorek.

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"

Výstup předchozího příkladu je následující:

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

Při použití částečný kód aktivní vzorky někdy jednotlivé volby mohou být nesouvislý nebo vzájemně se vylučující, ale není třeba.V následujícím příkladu čtverec vzorek a vzorek krychle nejsou nesouvislý, protože některá čísla jsou čtverce a krychlí, například 64.Následující program vytiskne všechna celá čísla až 1000000 čtverce a krychle.

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)

Výstup je následující:

1
64
729
4096
15625
46656
117649
262144
531441
1000000

Parametrizované aktivní vzorky

Vzorky aktivní vždy trvat alespoň jeden argument pro hledanou položka , ale také další argumenty mohou přijmout v tomto případě název parametrizované aktivní vzorek platí.Další argumenty umožňují zadat obecné vzorek.Aktivní vzorky, používající regulární výrazy pro analýzu řetězce často patří například regulární výraz jako dodatečný parametr, jako v následující kód, který také používá částečný kód aktivní vzorek Integer definované v předchozím příkladu kódu.V tomto příkladu řetězce používající regulární výrazy pro různé formáty dat jsou dána upravit obecné aktivní vzorek ParseRegex.Aktivní vzorek celé číslo se používá pro převést odpovídající řetězce na celá čísla, které mohou být předány konstruktorDateTime.

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())

Výstup předchozího kódu je následující:

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

Viz také

Referenční dokumentace

Shoda výrazy (F#)

Další zdroje

F# Language Reference