千家信息网

F#数据类型Discriminator Union如何理解

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,F#数据类型Discriminator Union如何理解,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。题外话:我写这个主要是希望更
千家信息网最后更新 2025年01月17日F#数据类型Discriminator Union如何理解

F#数据类型Discriminator Union如何理解,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

题外话:

我写这个主要是希望更多的.Net开发人员能了解F#,能在看到F#代码时不被一堆奇怪的符号搞晕(其实也没几个奇怪的符号).我没有说过F#比别的语言好、会取代C#之类的话,只是希望更多的人能了解并开始使用F#(C#用的多了,了解下F#换换脑子也是挺不错的)。 写的例子、代码都比较简单,希望大家多多包涵。可能有朋友手头没有VSTS 2010 Beta1,这个没有关系,因为F#还有一个为VSTS 2008准备的独立安装包,大家可以在这里下载安装它。

F#数据类型之Discriminator Union简介

上节我们通过一个简单的例子了解了怎样在F#中声明变量,定义函数,并且用到了F#中两个重要的数据类型List和Array,今天我主要介绍F#中一个非常重要的immutable数据类型Discriminated Unions。还是首先看一个例子,这是我写的一个简单的生成二分查找树的例子。

type Tree<'a> =       | Node of 'a * Tree<'a> * Tree<'a>      | Nil    let generateBinarySearchTree l =       let rec insert a = function             | Node(root,left,right) when a < root   -> Node(root, (insert a left), right)          | Node(root,left,right) when a > root   -> Node (root,left, (insert a right))                       | Nil -> Node(a, Nil,Nil)                            let rec loop acc = function          |[] -> acc          |hd::tl -> loop (insert hd acc) tl            loop Nil l   let tree1 = generateBinarySearchTree [5;3;9;4;6;7]

我们首先来看前三行,没错,这就是今天要重点介绍的F#数据类型:Discriminator Union

type Tree<'a> =       | Node of 'a * Tree<'a> * Tree<'a>      | Nil

首先注意到我们这次使用的是type,而不是前面常用的let关键字。 F#中使用type关键字来定义用户自定义类型,在这里我们定义了一个类型Tree, 那么Tree后面的<'a>又是啥意思呢?可能有的朋友己经猜到了,它表示a是一个泛型占位符,在实际使用中,a可能是int型,也可能是string等等(注意别忘了a前面的单引号)。后面二行就是具体的Tree定义了,它表示我们定义的Tree有两种可能,有可能是Node,也有可能是Nil。 我们先来看***种情形

Node of 'a * Tree<'a> * Tree<'a>

它表示Node的类型是 'a * Tree<'a> * Tree<'a>, 那么这个又表示什么呢?其实它是F#中另外一种重要的immutable类型Tuple, Tuple很容易理解,它表示把一个数据集合在逻辑上看作是一个整体。看个例子大家就明白了(注意分隔符是逗号)

let s2 = (1,"hello")

(在这里我们定义了一个类型为int * string的Tuple. 要使用它里面的值也很简单,我们可以声明新的变量并用s的值来初始化它们。 let i,s = s2就表示我们声明了int型变量i,它的值为1, string型变量s,它的值是2)

回到我们的例子中来, 'a * Tree<'a> * Tree<'a> 就很容易理解了,因为在定义Discriminated union时可以递归引用自己。

Tree的第二种情形Nil很简单,它表示一个什么都没有的空结点.

通过我上面详细的解释,我想大家也明白了什么是Discriminated union, 它表示一组有限的可选情形,并且每种情形都有自己的严格定义。回到我们上面的例子,Tree有两种情形,要么是 'a * Tree<'a> * Tree<'a>的Node,要么是一个空的Nil。大家也看到了它和Pattern matching结合使用非常频繁,这下明白为什么叫Discriminated union了吧

如果你认真读到上一篇文章的话,接下来构建二分查找树的代码比较简单,我就不解释了。我们接下来看如何判断某一个值是否在一个构建好的二分查找树中。

let rec tryFind x = function      | Node(root,_,_) when x = root -> Some(x)      | Node(root,left,_) when x tryFind x left      | Node(root,_,right) when x > root -> tryFind x right      | _ -> None

首先要注意我使用了五个'_',前面四个看起来好象和***的一个有些不一样。记得我在上一篇中说过'_'用在Pattern Matching中用来匹配所有别的情况,而且我说过F#里的Pattern Matching要比C#中的Switch强大,在这里我们就看到了它的强大之处,它可以在找到匹配后,为匹配的各部分绑定一个变量名来方便我们后面的调用,在绑定时如果我们仅仅对某些部分感兴趣,那么我们就可以使用'_'来代替我们不感兴趣的部分(注意'_'只能绑定一个对应部分,要对应两个我们就要敲两个'_','_').

其次我们注意到tryFind的返回值好象有两种情况呀,Some(x)和None,一个函数怎么能返回两种不同类型的值呢? 呵呵,忘记我们今天主要在讲Discriminated union了?这是个F#里事先定义好的一个discriminated union,它有自己的名字叫Option,它的定义非常简单,有了前面的基础,这个就不需要我解释了吧。

type option<'a> =       |Some of 'a      |None

关于F#数据类型Discriminator Union如何理解问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

类型 数据 例子 变量 情形 更多 部分 重要 两个 代码 问题 C# 解释 强大 关键 关键字 兴趣 函数 就是 情况 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 内网服务器ssh端口转发 校园网络安全对策与措施 好评的重庆服务器托管云主机 网络技术落后用英语怎么说 失落方舟美服服务器身份验证失败 网络安全文科生可报吗 国内好的线上网络安全大赛 中国人寿软件开发给户口吗 网络安全师证书 广州盒子互联网科技有限公司售后 软件开发wbs词典 专业网络安全供应商 金山区大规模软件开发产品介绍 网络安全法公民权利 无锡合同管理软件开发平台 未来之役台服链接不到服务器 切实守好企业网络安全主阵地 简述网络安全的案例 数据库的延迟更新技术例题 武定县网络安全事件应急预案 哔哩哔哩服务器崩了补偿哪里领 酒店网络安全系统维护 在哪里可以找到软件开发团队 unity做软件开发 道康宁材料安全数据库 贵州应急广播服务器虚拟主机 rpg服务器管理指令 我的世界暗夜之光服务器 网络安全的关键因素是 小平网络技术
0