`
tianshibaijia
  • 浏览: 1125333 次
文章分类
社区版块
存档分类
最新评论

5.4.4 实现选项类型的操作

 
阅读更多

5.4.4 实现选项类型的操作

绑定和映射的实现有类似的结构,因为,两者都是高阶函数,模式匹配依据一个选项值。我们来看一看 F# 和 C# 的实现,是在 C# 中编码函数概念的好示例。让我们从清单 6.14 开始,显示了映射操作的实现。

Listing 6.14 Implementing the map operation in F# and C#

F# Interactive C#

> let map f input =
match input with
| None –> None
| Some(value) –>
Some(f(value));;
val map :
('a -> 'b) –>
'a option -> 'b option

Option Map(this Option
input, Func f) {
T v;
if (input.MatchSome(out v))
return Option.Some(f(v));
else
return Option.None();
}

实现首先检查给定的选项值作为参数值。当值为 None,它立即返回 None 作为结果。注意,我们不能返回作为参数值的 None 值,因为类型可能不同。在 C# 版本中,更为明显。结果的类型是 Option,而参数值的类型是 Option。

当参数值的值,匹配差别【送别】联合的 Some 情况,就得到 T 类型的值,并使用提供的函数(或 Func 委托),把它映射到 R 类型的值。因为,从这个操作返回的值的类型应该是 Option,需要再次使用 Some 构造函数把这个值打包。

映射和绑定操作的源代码是很相似,但也有一些重要的差异。现在让我们看一下,在清单 6.15 中的第二组操作。

Listing 6.15 Implementing the bind operation in F# and C#

F# Interactive C#

> let bind f input =
match opt with
| None –> None
| Some(value) -> f(value)
;;
val bind :
('a -> 'b option)
-> 'a option -> 'b option

Option Bind(this Option
input, Func<T, Option> f) {
T value;
if (input.MatchSome(out value))
return f(value);
else
return Option.None();
}

绑定操作同样从模式匹配开始,依据对作为参数值给定的选项值。当选项值是 None 时,它立即返回 None,就像前面的情况一样。区别在于,当选项携带实际值。我们再次应用来自参数值的函数,但这一次,不需要把结果打包到Some构造函数中 。从函数中返回的值已经是一个选项,并且可以从类型签名中看出,这也正是我们想要返回的类型。这意味着,即使在 Some 情况下,绑定操作仍可能返回 None,具体情况要取决于用户所提供的函数。

通常,F# 版本把原始值作为最后一个参数值,以启用流及偏应用,而 C# 版本采用扩展方法。现在,我们看一下如何在 C# 中重写前面的示例,使用新创建的方法。

在 C#中使用选项类型

扩展方法使我们可以用流畅的风格来编写使用绑定和映射的代码。因为,括号中的数字可能会造成混乱,因此,要注意对映射的调用是嵌套在 lambda 函数内部的,作为参数值给绑定的:

Option ReadAndAdd() {
return ReadInput().Bind(n =>
ReadInput().Map(m => m + n));
}

在 C# 中,使用高阶函数与显式处理选项类型之间的区别更为重要。C# 不直接支持类似差别联合之类的类型,但如果我们提供的类型有适当的处理函数,代码将变得可读。这是重要的一点,牢记,在 C# 中写函数式程序:一些低级的构造可能感觉不自然的,但由于 lambda 函数,我们在 C# 中也可以编写优雅的函数代码。

到目前为止,我们已经看到了如何使用高阶函数处理多值和可选值。在前一章中,我们谈到了最后一种值是函数。在下一节,我们将看到,也可以写非常有用的高阶函数值来处理函数值。

分享到:
评论

相关推荐

    软件分析建模与PowerDesigner实现.part1.rar

    5.4.4 基于SWBP1.x业务流程语言的BPM 5.4.5 基于SOA匕务流程语言的BPM 5.5 协作型BPM 5.6 业务流程模型应用实例 5.6.1 订单业务流程模型的建立方法 5.6.2 订单业务流程模型的修改方法 5.6.3 Web服务的对象模型 第6章...

    软件分析建模与PowerDesigner实现.rar.part2

    5.4.4 基于SWBP1.x业务流程语言的BPM 5.4.5 基于SOA匕务流程语言的BPM 5.5 协作型BPM 5.6 业务流程模型应用实例 5.6.1 订单业务流程模型的建立方法 5.6.2 订单业务流程模型的修改方法 5.6.3 Web服务的对象模型 第6章...

    软件分析建模与PowerDesigner实现.rar.part3

    5.4.4 基于SWBP1.x业务流程语言的BPM 5.4.5 基于SOA匕务流程语言的BPM 5.5 协作型BPM 5.6 业务流程模型应用实例 5.6.1 订单业务流程模型的建立方法 5.6.2 订单业务流程模型的修改方法 5.6.3 Web服务的对象模型 第6章...

    iphone开发入门经典源码

    5.4 连接到代码 5.4.1 在Xcode中启动InterfaceBuilder 5.4 .2实现概述 5.4.3 输出口和操作 5.4.4 对象身份 5.5 小结 5.6 问与答 5.7 作业 5.7.1 测验 5.7.2 答案 5.7.3 练习 5.8 进一步探索 第6章 模型觏图-控制器...

    清华大学Linux操作系统原理与应用

    D.2.2 gcc/egcs的主要选项 240 D.2.3 gdb简介 240 D.2.4 gdb的常用命令 241 D.2.5 gdb使用示例 242 D.3 GNU make和makefile 243 D.3.1 GNU make 243 D.3.2 makefile的基本结构 243 D.3.3 makefile的变量 244 D.3.4 ...

    jQuery权威指南366页完整版pdf和源码打包

    9.2.2 数组和对象的操作 9.2.3 字符串操作 9.2.4 测试操作 9.2.5 url操作 9.3 工具函数的扩展 9.4 其他工具函数—$.proxy() 9.5 综合案例分析—使用jquery扩展工具函数实现对字符串指定类型的检测 ...

    疯狂JAVA讲义

    8.1.2 手动实现编译时检查类型 293 8.1.3 使用泛型 294 8.2 深入泛型 294 8.2.1 定义泛型接口、类 295 8.2.2 从泛型类派生子类 296 8.2.3 并不存在泛型类 298 8.3 类型通配符 298 8.3.1 使用类型通配符 300 ...

    精通Windows.API-函数、接口、编程实例.pdf

    5.4.4 管理其他进程的虚拟内存 143 5.5 内存操作与内存信息管理 144 5.5.1 复制、填充、移动、清零内存块、防止缓冲区溢出 144 5.5.2 获得当前系统内存使用情况 146 5.5.3 判断内存指针的可用性 147 5.6 ...

    网络编程实用教程(第三版).zip

    5.4.4 客户端程序主要功能的代码和分析 135 5.4.5 创建服务器端程序 142 5.4.6 服务器端程序的流程和消息驱动 144 5.4.7 点对点交谈的服务器端程序主要功能的代码和分析 145 5.5 用CSocket类实现聊天室程序...

    windows驱动开发技术详解-part2

    实现操作 系统与硬件快速信息交换是电子系统设计的关键。  通用操作系统硬件驱动程序的开发,编写者不仅需要精通硬件设备、计算机总线,而且需要Windows 操作系统知识以及调试技巧。学习和掌握Windows硬件驱动...

    jQuery权威指南-源代码

    9.5 综合案例分析—使用jQuery扩展工具函数实现对字符串指定类型的检测/305 9.5.1 需求分析/305 9.5.2 效果界面/305 9.5.3 功能实现/306 9.5.4 代码分析/309 9.6 本章小结/311 第10章 jQuery性能优化与最佳...

    Windows驱动开发技术详解的光盘-part1

    实现操作系统与硬件快速信息交换是电子系统设计的关键。  通用操作系统硬件驱动程序的开发,编写者不仅需要精通硬件设备、计算机总线,而且需要Windows操作系统知识以及调试技巧。学习和掌握Windows硬件驱动程序的...

Global site tag (gtag.js) - Google Analytics