F#程序设计-函数式编程之Discriminated Unions
来源:互联网 发布:c语言考公共基础知识吗 编辑:程序博客网 时间:2024/05/22 12:14
discriminated union是函数式编程中的一个基础类型,要定义discriminated union类型,需要用到type关键字,后面接着的是discriminated union类型的名字,然后用"|"分隔每一个值。在discriminated union类型中的每一个值都被称作为union case。例如一套扑克有四种牌,红桃、方块、梅花、黑桃。我们可以定义一套牌的discriminated union类型:
> type Suit =
- | Heart
- | Diamond
- | Spade
- | Club;;
type Suit =
| Heart
| Diamond
| Spade
| Club
> let suits = [ Heart; Diamond; Spade; Club ];;
val suits : Suit list = [Heart; Diamond; Spade; Club]
你也可以利用union case把可选的数据关联起来,比如下面的例子,在一副牌中,每张牌都都有四种类型。除了A、J、Q、K四张牌外,剩下的1到10都可以利用一个元组类型来关联四种牌型。
type PlayingCard =
| Ace of Suit
| King of Suit
| Queen of Suit
| Jack of Suit
| ValueCard of int * Suit
> let deckOfCards =
- [
- for suit in [ Spade; Club; Heart; Diamond ] do
- yield Ace(suit)
- yield King(suit)
- yield Queen(suit)
- yield Jack(suit)
- for value in 2 .. 10 do
- yield ValueCard(value, suit)
- ];;
val deckOfCards : PlayingCard list =
[Ace Spade; King Spade; Queen Spade; Jack Spade; ValueCard (2,Spade);
ValueCard (3,Spade); ValueCard (4,Spade); ValueCard (5,Spade);
ValueCard (6,Spade); ValueCard (7,Spade); ValueCard (8,Spade);
ValueCard (9,Spade); ValueCard (10,Spade); Ace Club; King Club; Queen Club;
Jack Club; ValueCard (2,Club); ValueCard (3,Club); ValueCard (4,Club);
ValueCard (5,Club); ValueCard (6,Club); ValueCard (7,Club);
ValueCard (8,Club); ValueCard (9,Club); ValueCard (10,Club); Ace Heart;
King Heart; Queen Heart; Jack Heart; ValueCard (2,Heart);
ValueCard (3,Heart); ValueCard (4,Heart); ValueCard (5,Heart);
ValueCard (6,Heart); ValueCard (7,Heart); ValueCard (8,Heart);
ValueCard (9,Heart); ValueCard (10,Heart); Ace Diamond; King Diamond;
Queen Diamond; Jack Diamond; ValueCard (2,Diamond); ValueCard (3,Diamond);
ValueCard (4,Diamond); ValueCard (5,Diamond); ValueCard (6,Diamond);
ValueCard (7,Diamond); ValueCard (8,Diamond); ValueCard (9,Diamond);
ValueCard (10,Diamond)]
discriminated union类型也可以递归。如果你想定义一个相互递归的discriminated unions,可以像定义函数一样,不同的是它们必须用and关键字连在一起。例如,在下面的代码中,我们定义了一个编程语言的简单格式:
type Statement =
| Print of string
| Sequence of Statement * Statement
| IfStmt of Expression * Statement * Statement
and Expression =
| Integer of int
| LessThan of Expression * Expression
| GreaterThan of Expression * Expression
为了表达一个if语句:
if (3 > 1)
print "3 is greater than 1"
else
print "3 is not"
print "greater than 1"
在上面定义的简单的语言格式中,我们可以利用递归来实现if语句的表达式:
let program =
IfStmt(
GreaterThan(
Integer(3),
Integer(1)
),
Print("3 is greater than 1"),
Sequence(
Print("3 is not"),
Print("greater than 1")
)
)
在树结构中运用Discriminated Unions
Discriminated unions类型非常适合用于代表树形结构,下面的代码定义了一个二叉树,并且用一个函数来遍历并打印出这棵树:
type BinaryTree =
| Node of int * BinaryTree * BinaryTree
| Empty
let rec printInOrder tree =
match tree with
| Node (data, left, right)
-> printInOrder left
printfn "Node %d" data
printInOrder right
| Empty
-> ()
比如,我们想生成下面这样的一颗树:
2
/ /
1 4
/ /
3 5
就可以这样编写代码:
let binTree =
Node(2,
Node(1, Empty, Empty),
Node(4,
Node(3, Empty, Empty),
Node(5, Empty, Empty)
)
)
printInOrder tree
模式匹配
discriminated unions同样也可以用于模式匹配,在匹配规则中,用unions case来作为模式标签。如果一个unions标签用数据关联,你就可以根想在正常的模式匹配中样使用模糊匹配或者值匹配。下面的例子还是通过玩纸牌的游戏来说明模式匹配:
let describeHoleCards cards =
match cards with
| []
| [_]
-> failwith "Too few cards."
| cards when List.length cards > 2
-> failwith "Too many cards."
| [ Ace(_); Ace(_) ] -> "Pocket Rockets"
| [ King(_); King(_) ] -> "Cowboys"
| [ ValueCard(2, _); ValueCard(2, _)]
-> "Ducks"
| [ Queen(_); Queen(_) ]
| [ Jack(_); Jack(_) ]
-> "Pair of face cards"
| [ ValueCard(x, _); ValueCard(y, _) ] when x = y
-> "A Pair"
| [ first; second ]
-> sprintf "Two cards: %A and %A" first second
- F#程序设计-函数式编程之Discriminated Unions
- 5.3.1 F# 中的差别联合(discriminated unions)
- F#程序设计-函数式编程之Records
- 泛型<编程>:可识别联合(Discriminated Unions)(1)
- 泛型<编程>:可识别联合(Discriminated Unions)(2)
- 泛型<编程>:可识别联合(Discriminated Unions)(3)
- F#程序设计-函数式编程之函数组合(Function Composition)
- F#程序设计-函数式编程之模式匹配
- F#程序设计-函数式编程之惰性加载
- F#程序设计-函数式编程之值的可变性
- F#程序设计-函数式编程之用函数风格来编程(1)
- F#程序设计-函数式编程之用函数风格来编程(2)
- F#程序设计-面向对象编程之继承
- 一个可识别联合(Discriminated Unions)的C++实现
- 一个可识别联合(Discriminated Unions)的C++实现
- F# 函数式编程
- F#程序设计-F#语言基础之函数(1)
- F#程序设计-F#语言基础之函数(2)
- 在DirectShow的视频图像上叠加线条和文字
- 1
- SQL SERVER DBCC命令解释
- Windows共享连接上网选ICS还是NAT?
- Ubuntu8.04安装snmp
- F#程序设计-函数式编程之Discriminated Unions
- Windows Mobile开发文章收藏
- (转)项目开发管理SDEM
- jsp调用javabean实例
- 人生四课-------小故事
- 查看编译参数
- Windows Mobile 开发资源(精)
- 2012诺亚方舟中国号船票正式销售!
- 选择对话框