![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
可组合
文章平均质量分 65
心想才事成
这个作者很懒,什么都没留下…
展开
-
15 第十五章 创建可组合函数库
15 第十五章 创建可组合函数库 本章介绍■ 设计函数式连接符库■ 处理时变值■ 组合时变值与绘图■ 开发金融合同模型库 函数式编程表现出来的很多方面的设计原则,是可组合性(compositionality)。这意味着,可以使用组合操作,从几个基元构建出复杂的结构。我们将描述一般意义上的可组合化,因为它可以以无数的形式出现。让翻译 2011-12-09 20:43:42 · 538 阅读 · 0 评论 -
15.3 行为的计算
15.3 行为的计算 在本节中,我们会写几个工具函数,来帮助处理行为。虽然我们在这个阶段实验,但这一节中的大多数代码会用实现动画示例中。我们会首先在 F# 中实现这些函数,用 F# Interactive 进行测试,然后,重新在 C# 中实现最重要的部分。 为了测试任何使用行为的代码,我们需要实现的第一件事,是一个函数,在指定的时间读取行为的值。翻译 2011-12-16 16:51:32 · 604 阅读 · 0 评论 -
15.5.1 F# 中实现的动画形式
15.5.1 F# 中实现的动画形式 在本节中,我们将实现显示动画的窗体。在 F # 中,特别有趣,因为,我们将在 F# Interactive 中使用它,创建与实验动画。在这里,F# 开发的典型风格是非常不同于 C#。在 C# 中,我们会实现窗体,创建动画,编译应用程序,然后运行。在 F# 中,我们会实现窗体,把它装载到 F# Interactive,然后,尝试写一些动画翻译 2011-12-26 14:41:42 · 618 阅读 · 0 评论 -
15.5.2 使用行为创建动画
15.5.2 使用行为创建动画 我们已经有了创建动画的所有基础部件和显示的表单,现在,可以开始创建动画了。我们将从绘制两个彩色的圆开始,以前在 F# 中已经创建了,创建移动的动画。本节中,我们只使用 F#,因为将使用 F# Interactive 进行实验。你会看到,我们写的基元提供了很大的灵活性,我们会考虑可能用动画图形要做的其他操作。之后,还要回到 F# 和 C# 去实翻译 2011-12-26 14:42:45 · 509 阅读 · 0 评论 -
15.5.3 添加动画基元
15.5.3 添加动画基元 我们的目标是使构造动画的代码尽可能声明性和简单,为此,我们要提供专门为创建动画而设计的基元。我们已经看到,已经可以做需要的任何事情,只用现有的处理行为和绘图的函数,但是,如果我们可以使用专门的用于创建动画的基元,而不是显式使用提升,代码看起来会更优雅。让我们首先看一下处理绘图的函数。 创建用于动画的绘图基元翻译 2011-12-27 12:30:48 · 651 阅读 · 0 评论 -
15.5.4 创建太阳系的动画
15.5.4 创建太阳系的动画 至此,我们已经实现了动画库的所有类型和函数。虽然我们使用的是 F# Interactive,但是,把库的核心部分保存到一个单独的文件是个好主意(例如,Animations.fs)。然后,我们可以加载整个库,使用 #load 指令,将文件名作为参数。这种方式,也确保该内部类型扩展(包括我们添加到行为的运算符)正确加载,因为,内部类型扩展必须用相翻译 2011-12-28 13:26:31 · 711 阅读 · 0 评论 -
15.6 开发金融建模语言
15.6 开发金融建模语言 本章到目前为止,我们所讨论的大多数概念,如果你计划设计自己的函数库或 DSL,都是需要知道的。为了给你一定的概念,为了解决更加面向业务的问题,应该如何做,我们将勾画一个库,它能够用于对金融合同建模。这个示例的动机是 Simon Peyton Jones 等人的一篇文章《组合合同:在金融工程中的冒险》[Jones, Eber, Seward, 20翻译 2011-12-28 13:27:19 · 782 阅读 · 0 评论 -
16.2.2 实现 switch 函数
16.2.2 实现 switch 函数 我们在上一节描述了 switch 函数的行为方式,其实现并不比直接把描述转换成代码更多,如清单 16.8 所示。关键点是,这个函数将返回一个行为,它使用存储在可变变量中的实际行为。每当发生事件时,我们会更新可变变量,所以,任何后续的对这个行为值的请求,都使用新的结果。注意,可变状态的这种使用方式,对用户是隐藏的,所以,最终用户代码可以是声明式翻译 2012-01-11 16:51:38 · 707 阅读 · 0 评论 -
16.2.1 使用 switch 函数
16.2.1 使用 switch 函数 我们首先来看这个示例,然后,再描述 switch 函数的实现。这里是它的类型,对于我们理解它,这是一个良好的开端: val switch : Behavior -> IObservable> -> Behavior 这个函数的结果是一个行为,表示随时间而变化的 'T 值。这意味着,这个函数以某种方式构造了一个行为,使用翻译 2012-01-11 16:29:10 · 829 阅读 · 0 评论 -
15.6.1 建模金融合同
15.6.1 建模金融合同 金融业使用了大量的合同类型,包括掉期和期货(swaps and futures)。合同一般指定买进或卖出哪些商品,在什么时候,什么价格。当创建处理合同的应用程序时,可以为每个已知类型的合同直接硬编码支持。不幸的是,会有大量的选项,因此,这种解决方案不会非常灵活。 相反,我们将创建一种语言,能够描述一般的合同。合同最基本组成部分是贸易翻译 2011-12-30 12:10:25 · 794 阅读 · 0 评论 -
15.6.2 定义基元
15.6.2 定义基元 首先要定义将要处理的值类型,然后,实现几个可以在以后组合的基元。基元数据类型叫 Contract,表示可能出现在特定日期和时间的交易。 声明 CONTRACT 类型 你可以看到在清单 15.23 中,Contract 类型与动画示例中的行为类型很相似,它是一个差别联合,只有一个识别器,名为 ContractFu翻译 2011-12-30 12:12:07 · 674 阅读 · 0 评论 -
15.6.3 使用建模语言
15.6.3 使用建模语言 也许有关可组合库最有价值的事情,就是可以使用由库设计人员提供基本的基元,通过组合,来创建更复杂的函数。这样,就让库更灵活,因为库的用户(这里的金融专家)可以创建他们需要的基元。作为核心库的设计人员,我们只需要提供足够丰富的基元,允许用户建立更多的。 清单 15.25 演示这样定义的两个函数,根据刚刚创建的基元。第一个定义的函数,生成一个交易窗口翻译 2011-12-30 17:03:38 · 587 阅读 · 0 评论 -
15.7 第十五章小结
15.7 第十五章小结 本章开始,我们讨论了面向语言(language-oriented)的编程风格,特别是关于创建内部 DSLs 技术。我们简要提及抽象值表示技术,在这种技术下,通常设计一种数据类型(特别是差别联合)来表示连接符。接下来,我们讨论了流畅的接口(fluent interfaces),它在 C# 中尤其有用,和组合库,在函数式编程语言中使用。 我们在这一章用翻译 2011-12-30 17:04:01 · 537 阅读 · 0 评论 -
15.3.1 读取值
15.3.1 读取值 计算行为在给定时间的值很容易,其内部表示为一个函数,取时间作为参数值,计算出值,所以,我们需要执行这个函数。清单 15.7 显示函数,叫 readValue,取时间和行为作为参数,返回行为的值。有了这个函数,就可以从我们先前创建的基元行为中读取值。 Listing 15.7 Reading values of behaviors at the spec翻译 2011-12-16 15:28:02 · 579 阅读 · 0 评论 -
15.5 创建动画
15.5 创建动画 在这一章开始,我们说过要创建动画库,在这里,很多页都过去了,还没有看到一个动画。这应该是十分清楚的,我们一直在构建的所有基础,都是为了对我们的绘图进行动画处理更容易。 让我们简单回顾一下,到目前为止所做的工作。我们创建了一个类型 Behavior,表示行为随时间变化的值,还有一些函数,用来基于旧的行为创建新的行为。我们还创建了一个绘图类型(翻译 2011-12-21 16:41:21 · 555 阅读 · 0 评论 -
15.2.4 在 F# 中创建简单的行为
15.2.4 在 F# 中创建简单的行为 我们将从复制刚才在 C# 中已经实现的功能开始。清单 15.6 实现两个行为值(wiggle 和 time),和一个用于创建常量行为的函数(forever)。 Listing 15.6 Primitive behavior functions and values (F#) > open System;;> le翻译 2011-12-13 17:23:25 · 496 阅读 · 0 评论 -
15.1 可组合设计方法
15.1 可组合设计方法 让我们首先回顾一下,我们可以把可组合设计的概念变成现实。用几个基元组合成复杂结构的想法,在 LISP 语言中已经使用很长时间了。我们会分析 LISP 的一个示例,将给我们在 F# 和 C# 中,进一步讨论可组合库,提供一个很好的背景。翻译 2011-12-10 13:48:00 · 544 阅读 · 0 评论 -
15.1.2 定义符号
15.1.2 定义符号 LISP 代码可读性很好,很容易理解它的意思,代码不展现任何技术细节。我们不能说,要创建一个对象,把动画表示成可以处理的树形数据结构,或者要创建一个函数,知道如何绘制这个动画。这是有关声明式编程的好事情,我们只要使用这些库,无需考虑技术细节。 当然,技术细节还是要在某个地方表示的,即把它们实现成库。在 F# 和 C# 中,创建可组合库的翻译 2011-12-10 19:53:52 · 875 阅读 · 0 评论 -
15.3.2 将函数应用到行为
15.3.2 将函数应用到行为 在早先描述行为时,我们解释过,行为是一个复合值,相似性在于 Behavior 和 Option 之间。两者都是包含另一个值的复合值,但有不同的方式。选项类型的不寻常,在于它可能为空,而行为的不寻常,在于值依时间而变。 这个比喻表明行为的方向。我们已经看到,Option.map 在几个不同的上下文中,指定的函数应用到由该选项携带的翻译 2011-12-18 10:52:08 · 631 阅读 · 0 评论 -
15.4.1 表示绘图
15.4.1 表示绘图 在第 2 章,我们用形状的概念来演示差别联合。对于绘图应用程序,这将是一个不错的选择,应用程序需要了解形状的结构。对于我们动画库,这不是特别灵活,所以,我们将使用更具扩展性的表示形式。在 C# 中,绘图将是一个接口,有一个方法绘制图形对象。它可以更简单地表示为一个函数,我们还想要隐藏其内部表示形式。 F# 版本将按 C# 的风格,也使用接口。原因是翻译 2011-12-19 16:09:49 · 1069 阅读 · 0 评论 -
15.1.1 从符号组合出动画
15.1.1 从符号组合出动画 除其他外,LISP 语言以其简单但功能强大的语法闻名。当写任何复杂的程序时,你总是最终定义自己的基元,然后指定它们的意思。下面的示例演示如何能定义一个简单的动画,使用 LISP 的语法。该代码创建两个移动的盘子:一个绿色,直径为 50 ,一个小一点,红色, 直径 20。绿色的围绕点 (0,0)以 100 像素的半径旋转,红色在两个指定点之间移翻译 2011-12-10 15:52:02 · 636 阅读 · 0 评论 -
15.1.3 可组合值
15.1.3 可组合值 把问题描述为值,是把"语言"嵌入 F# 中的最简单的方法。这仅适用于简单的问题:我们不要指定任何复杂行为(比如,过滤函数的断言) ,和只需要通过组合基元对象或集合,并指定它们的属性,就能描述的大多数的问题。 当代码有效地描述值时,我们可以在 F# 中实现它,通过创建类型,能够创建指定所有属性的值。表示这类问题的最常见的 F# 类型,是差翻译 2011-12-11 19:23:53 · 511 阅读 · 0 评论 -
15.2.3 在 C# 中创建简单的行为
15.2.3 在 C# 中创建简单的行为 我们将从创建行为的几个基本函数开始。一旦有了一个好的方式进行可视化行为以后,返回到这个主题,并添加有趣的构造。 创建行为最简单的方法,是取一个我们可以直接使用的函数,作为行为的底层表示。这将是一个内部方法,用于其他基元的实现。因为我们要对象的创建打包到一个方法中,可以在非泛型类中,创建一个泛型方法,并使用 C# 的类型推断,翻译 2011-12-13 16:41:52 · 735 阅读 · 0 评论 -
15.2.1 介绍函数式动画
15.2.1 介绍函数式动画 在这一章中我们实现的库,很大程度上是由 Fran 激发的。我们重点关注单独的动画,不会详细讨论响应事件。在下一章,我们将讨论如何扩展库来支持响应图形用户界面编程。动画可以使用时变值,进行巧妙的建模。在 Fran 中,这些值称为行为,我们也使用这个名字。 注意 在我们的动画系统中,行为是一个时变值,它可以表翻译 2011-12-12 20:34:40 · 408 阅读 · 0 评论 -
15.4.2 创建和组合绘图
15.4.2 创建和组合绘图 我们要保持事情,简单地画一个圆。我们可以用类似的方式,实现很多其他类型,但是,我们来看一个例子,可以添加更多的绘图。精确的形状并不是特别重要的,在我们可以讨论的更有趣的组合的话题之前,需要一些具体的东西。 创建和移动圆 创建绘图,大约就是在图形对象上提供绘制的函数,图形对象是这个函数参数值。图形类型具有翻译 2011-12-21 16:15:45 · 740 阅读 · 0 评论 -
15.2.2 介绍行为
15.2.2 介绍行为 行为很大程度上是独立于动画库的。它们表示的值随时间变化:它不可能与图形或绘图相关。行为可能模拟网络流量、潮汐运动、股票价格,机器人的感官输入值,比如温度、或者任何其他随时间变化的测量。 这意味着,我们可以首先实现行为,不限制我们自己的动画。以通常的函数方式,我们首先考虑如何要表示行为,然后,实现一些简单的行为。我们已经创建了一些行为,能够将它们应用翻译 2011-12-13 14:27:19 · 570 阅读 · 0 评论 -
15.1.4 可组合函数和对象
15.1.4 可组合函数和对象 创建可组合库的第二个选项,是构建一些函数或对象,表示声明性的规范,并可以执行。这限制了用组合对象所能做的操作,因为,操作是每个基元的一个固有部分。事实上,许多时候,只需要执行单个操作,比如,绘制动画帧,或计算金融合同的交易。我们可以轻松地增加新的基元,为可组合的基元实现新的方法。在函数式编程语言中,以这种方式写出的库,被称为连接符库(comb翻译 2011-12-12 19:53:32 · 525 阅读 · 0 评论 -
15.2 创建动画值
15.2 创建动画值 在函数式语言中,使用连接符库表达动画的想法来自一个叫 Haskell 的项目,叫 Fran,,由 Conal Elliott 和 Paul Hudak 在 1997 年创建,[Elliot, Hudak, 1997]。 Fran(是 functional reactive animations 的简称)可以创建动画,并指定动画如何响应事件,比如,鼠标单击。翻译 2011-12-12 20:15:00 · 427 阅读 · 0 评论 -
5.2.3 组合使用元组
5.2.3 组合使用元组 当考虑从函数应返回什么样的元组时,关注的主要问题是可组合性(compositionally),即期望如何使用元组?其他哪些函数可能会使用相同类型的元组?与程序中其他的类似情况保持一致吗?我们用一个示例来演示,将使用两种的方法,表示前面示例中的屏幕坐标和消息,假定已经有一个输出消息的函数printMessage,因此,这里就会省略其定义,函数的声明可能像这样:翻译 2014-10-20 11:28:00 · 593 阅读 · 0 评论