# 超越F#基础——活动模式

| 作者 Robert Pickering 0 他的粉丝 ，译者 朱永光 0 他的粉丝 发布于 2008年1月5日. 估计阅读时间: 21 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

F#是什么？

## 模式匹配

let intToString x =     match x with     | 1 -> "One"     | 2 -> "Two"     | 3 -> "Three"     | x -> Printf.sprintf "Big number: %i" x

open System let typeToString x =     match box x with     | :? Int32 -> "Int32"     | :? Double -> "Double"     | :? String -> "String"     | _ -> "Other"

type BinaryTree<'a> =     | Leaf of 'a     | Node of BinaryTree<'a> * BinaryTree<'a>

let rec printBinaryTreeValues t =     match t with     | Leaf x -> printfn "%i" x     | Node (l, r) ->         printBinaryTreeValues l         printBinaryTreeValues r

let printBinaryTree t =     let rec printBinaryTree t indent =         match t with         | Leaf x -> printfn ->"%sLeaf %i" indent x         | Node (l, r) ->             printfn "%sLeft Branch" indent             printBinaryTree l (indent + "    ")             printfn "%sRight Branch" indent             printBinaryTree r (indent + "    ")     printBinaryTree t "" printBinaryTree (Node ((Node (Leaf 1, Leaf 2)), (Node (Leaf 3, Leaf 4))))

Left Branch     Left Branch         Leaf 1     Right Branch         Leaf 2 Right Branch     Left Branch         Leaf 3     Right Branch         Leaf 4

## 活动模式

let (|Node|Leaf|) (node : #System.Xml.XmlNode) =     if node.HasChildNodes then         Node (node.Name, { for x in node.ChildNodes -> x })     else         Leaf (node.InnerText)

let printXml node =     let rec printXml indent node =         match node with         | Leaf (text) -> printfn "%s%s" indent text         | Node (name, nodes) ->             printfn "%s%s:" indent name             nodes |> Seq.iter (printXml (indent +"    "))     printXml "" node

let doc =     let temp = new System.Xml.XmlDocument()     let text = " <fruit>     <apples>         <gannySmiths>1</gannySmiths>         <coxsOrangePippin>3</coxsOrangePippin>     </apples>     <organges>2</organges>     <bananas>4</bananas> </fruit>"     temp.LoadXml(text)     temp printXml (doc.DocumentElement :> System.Xml.XmlNode)

let (|File| Directory|) (fileSysInfo : System.IO.FileSystemInfo) =     match fileSysInfo with     | :? System.IO.FileInfo as file -> File (file.Name)     | :? System.IO.DirectoryInfo as dir ->          Directory (dir.Name, { for x in dir.GetFileSystemInfos() -> x })     | _ -> assert false      // a System.IO.FileSystemInfo must be either a file or directory

open System let invar = Globalization.CultureInfo.InvariantCulture let style = Globalization.DateTimeStyles.None let (|ParseIsoDate|_|) str =     let res,date = DateTime.TryParseExact(str, "yyyy-MM-dd", invar, style)     if res then Some date else None let (|ParseAmericanDate|_|) str =     let res,date = DateTime.TryParseExact(str, "MM-dd-yyyy", invar, style)     if res then Some date else None let (|Parse3LetterMonthDate|_|) str =     let res,date = DateTime.TryParseExact(str, "MMM-dd-yyyy", invar, style)     if res then Some date else None

let parseDate str =     match str with     | ParseIsoDate d -> d     | ParseAmericanDate d -> d     | Parse3LetterMonthDate d -> d     | _ -> failwith "unrecognized date format" parseDate "05-23-1978" parseDate "May-23-1978" parseDate "1978-05-23" parseDate "05-23-78"

let (|ParseRegex|_|) re s =     let re = new System.Text.RegularExpressions.Regex(re)     let matches = re.Matches(s)     if matches.Count > 0 then         Some { for x in matches -> x.Value }     else         None let parse s =     match s with     | ParseRegex "\d+" results -> printfn "Digits: %A" results     | ParseRegex "\w+" results -> printfn "Ids: %A" results     | ParseRegex "\s+" results -> printfn "Whitespace: %A" results     | _ -> failwith "known type" parse "hello world" parse "42 7 8" parse "\t\t\t"

Ids: seq ["hello"; "world"] Digits: seq ["42"; "7"; "8"] Whitespace: seq ["\t\t\t"]

## F#资源

1. F#官方站点 ，可以找到编译器的最新版本和F#手册
2. Don Syme，F#开发带头人的博客，一个发布F#公告的最好地方，并且有一些关于F#各方面的短文
3. The Hub-FS，F#的社区站点，有博客和论坛
4. Robert Pickering的F#教程和资源
5. Flying Frog Consultancy的F#教程和资源

## 关于作者

Robert Pickering是一个软件工程师和一个技术作家。他目前工作于LexiFi，一个富有创新的ISV，特别专注于软件分析和处理复杂金融相关系统——如互换交易系统和期权交易系统。为了开发一个精确的方式来表示金融文件，LexiFi开创了在金融软件系统中函数式编程的运用。他的博客是：http://strangelights.com/blog