12.5.2 写计算

C# 查询表达式和 F# 计算表达式,可以使用函数,行为方式非标准(返回单子值),就好像返回普通值。我们在这一节使用的计算类型是 ValueWrapper <T>,因此,原始函数将返回值的类型是 ValueWrapper<T>,而不是 T。

实现这些函数,既可以使用其他的查询或计算表达式,也可以通过直接创建计算类型的值。有些计算表达式可以封装复杂的逻辑,所以,直接创建值可能有困难。这时,通常写一些返回这种计算类型的基本操作,再使用这些基本操作实现其他的一切。然而,构建 ValueWrapper <T> 类型的值并不困难。下面的代码演示了用 C#实现的一个方法,从控制台读一个数字,并把它打包到这个计算类型内:

ValueWrapper<int> ReadInt() {

int num =Int32.Parse(Console.ReadLine());

return newValueWrapper<int>(num);

}

这个方法从控制台读一个数字,并把它打包到  ValueWrapper <T> 类型。F# 版本同样简单,所以,就不在这里讨论了。重要的是,这些基本函数,是唯一需要知道任何类型的底层结构的,计算的其余部分,只需要知道类型所提供的全部基本操作(最重要的是 bind 和 return),是写查询或计算表达式所必需的。

我们定义好值标识符,即,在 F# 中表示为计算表达式(第 12.5.3 节),在 C# 中实现必要的扩展方法(第 12.5.4 节)以后,就能够轻松地处理这个类型的值了。注意,我们将使用的类型并没有实现 IEnumerable<T> 接口。查询语法和计算表达式的表示方法与序列无关,定义代码的含义,是通过一组使用 ValueWrapper <T> 类型的方法实现的。清单 12.18 的代码段,使用基本操作读两个整数,再进行计算。

清单 12.18 在 C# 和 F# 中用计算值进行计算


C#


F#


var v =

from n in ReadInt()   | [1]

from m in ReadInt()   |

let add = n + m

let sub = n – m

select add * sub;  [3]


value {

let! n = readInt()   | [2]

let! m = readInt()   |

let add = n + m

let sub = n – m

return add * sub }  [4]

在 C# 中,我们使用 from 子句提取值[1],而在 F# 中,我们是用自定义的值绑定实现的[2]。

计算完成以后,我们再把值打包到计算类型中。在 C# 中,使用 select 子句[3],在 F# 中,使用 return 基本操作[4]。

可以发现,C# 和 F# 代码的结构非常相似。这段代码并没有任何实际的用途,但是,它有助于我们理解非标准计算是如何运行的。唯一有意义的地方,是我们在 C# 写的代码,可以使用 let 子句,作为一个表达式,创建局部变量,这个子句很像 F# 中的 let 绑定,所以,整个代码就是一个表达式。

在下面的讨论中,我们将更多地关注 F# 版本,因为它能使解释原理更简单。在 C# 中的查询表达式语法是为写查询而量身定做的,所以,很难用于其他的计算类型。当我们实现了 F# 计算表达式之后,再回到 C#。

可以看到,清单 12.18 只用了两个基本操作。基本操作 bind 在调用计算基本操作时使用,基本操作 return 用于把结果打包成 ValueWrapper <int> 类型。接下来的问题可能是,F# 编译器如何使用这两个基本操作,解释计算表达式的,我们如何实现。

时间: 2024-07-30 14:31:22

12.5.2 写计算的相关文章

初学knockoutjs记录5——Computed observables依赖监控(2 Writable computed observables可写计算监控属性)

Writable computed observables 可写计算监控属性 可写监控属性的要求较高,并且在大多数场合下并不常用. 一般来说,计算监控属性拥有一个有其它监控属性计算得来的值,也正因如此它是通常是只读的,看起来很奇怪,但是,确实有可能让计算监控属性成为可写的,你只需要提供回调函数合理的使用可写的值做一些事情. 你可以像常规的监控属性那样使用计算监控属性,只要你有自定义的逻辑用来截获所有的读写操作.就像普通监控属性一样,你可以使用链接语法编写拥有多个监控属性或计算监控属性的对象模型,

12.7.3 使用计算表达式进行重构

在前一章,我们讨论过重构函数式程序的方法,最后一个主题是延迟性,它变改代码的执行方式,而不影响程序的结果.从某种意义上讲,添加延迟性也可看作是一种重构技术:计算表达式的类似之处在于,增加额外的代码,但不改变核心意思. 提示 在计算表达式和延迟性之间有密切的关系,使用 Lazy<'T> 计算类型,创建能够把代码转换成延迟计算的计算表达式,是有可能的.我们可以尝试实现自定义的计算,唯一的难度在于写 Bind 成员.在这里,我们不进行讨论,在本书的网站上可以找到其他的信息. 重要性在于,把标准的 F

12.5.1 声明计算类型

在这个示例中,计算的类型(在 Haskell 术语中的单子类型)称为 ValueWrapper<T>,它只是存储泛型类型参数T 的值,并不会为类型增加任何其他功能.这就是说,计算只处理标准值,但是,我们能够用 C# 中的查询表达式, F# 中的计算表达式,写代码(来增加功能). 清单 12.17 显示了在 C# 和 F# 中的类型声明.在 C# 中,我们创建简单的类,在 F# 中,将使用一个简单的只有一种情况的差别联合. 清单 12.17 C# 和 F# 中的计算值 // C# 的类声明 cl

【2016.12.11】JavaScrip计算自己活了多少天

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn"> <head> <met

有用函数编程

<序> 感谢 关于本书 关于封面 第一部分 学习函数式思维 第一章 不同的思维 1.1 什么是函数式编程? 1.2 通往有用函数编程之路 1.3 用函数式编程提高生产力 1.3.1 函数范式 1.3.2 声明式编程风格 1.3.3 了解程序的执行 1.3.4 设计并发友好的应用程序 1.3.5 函数风格怎样形成代码 1.4 函数式编程演示样例 1.4.1 用声明式风格表达意图 1.4.1.1 用 LINQ 处理数据 1.4.1.2 用 XAML 描写叙述用户界面 1.4.1.3 声明式函数动画

12.5.3 在 F# 中实现计算生成器

在计算表达式块前面的标识符,是类的实例,把所需的操作实现成为实例成员.许多操作都已经有了,我们根本不必要提供所有的,最基本的操作用 Bind 和 Return 成员实现.当 F# 编译器看到计算表达式,比如清单 12.18 时,会把它转换为使用这些成员的F# 代码.F# 示例转换成这样: value.Bind(ReadInt(), fun n –> value.Bind(ReadInt(), fun m–> let add = n + m let sub = n – m value.Retur

CDH5.12.0 中扩容增加计算节点

CDH5.12.0 中扩容增加计算节点 标签(空格分隔): 大数据平台构建 一: 环境准备 二: 增加节点环境系统初始化 三: 增加节点关于CDH5.12.0环境配置 四: 在CM 上面节点增加 一:环境的概述与准备 概述: 很多时候,企业的大数据环境(CDH5.12.0),根据使用的时间越来越长,空间会有不足的情况,集群的计算 能力也因此下降, 此时需要对将大数据的 集群环境进行扩容 增加计算节点. 1.1 系统逻辑部署图 1.2 安装文件详细信息列表: CM: cloudera-manage

for循环计算阶乘的和,for循环计算阶乘倒数的和

计算阶乘的和 1 //阶乘的和,5!+4!+3!+2! 2 3 int a = 5; 4 for(int b = 4; b > 0; b--) 5 { 6 a = a * b; 7 } //先定义好最大数的阶乘是多少 8 int c = a; 9 for(int n = 5; n > 1; n--) //当n等于2的时候,这是算的就是1的阶乘,所以后面取n>1 10 { 11 a = a / n; //利用数学公式,n! = (n + 1)!/(n + 1),再写出for循环计算 12

12.5.4 在 C# 中实现查询操作

在清单 12.14 中,当我们讨论序列和分析 SelectMany 操作时,已经知道可以把 C# 查询转换为方法调用.我们实现的查询,只支持以 select 子句结尾,而忽视那些仅对集合有用的情况,比如分组,这样,就需要实现 Select 扩展方法. 我们前面说过,第二个和随后的 from 子句会转换成对 SelectMany 方法的调用.当使用查询写计算时,我们使用 from 子句的方式,非常类似于F# let! 结构,表示非标准的值绑定,所以,经常会用到它,这就是说,我们还需要为 Value