
高阶函数
文章平均质量分 62
心想才事成
这个作者很懒,什么都没留下…
展开
-
12.1.1 使用高阶函数
12.1.1 使用高阶函数 在 F# 中,用于处理序列的函数在 Seq 模块中,我们将解释一个非常普通的函数,Seq.unfold。你可以看到,它与 fole 函数相对,它取一个集合,并把它"折"成单一值。unfold 取单一值,把它"展开"为一个序列。下面的代码片断展示了如何生成一个序列,包含把 10 个数字格式化为字符串:> let nums = Seq.翻译 2011-11-05 14:42:05 · 691 阅读 · 0 评论 -
6.1.2.2 F# 的管道运算符
6.1.2.2 F# 的管道运算符 使用管道运算符(|>),能够把函数的第一个参数写在左边,即,在函数名的前面。这是非常有用的,比如,想调用几个函数,处理序列中的值,想要找出第一个处理的值。下面的示例演示了反转 F# 列表,然后,得到一个元素: List.hd(List.rev [1 .. 5]) 这种写法并不优雅,因为,写的操作顺序与执行的顺序相反,且要处理的值在右边,括翻译 2014-10-28 15:04:33 · 1936 阅读 · 0 评论 -
6.7.2 理解列表函数的类型签名
6.7.2 理解列表函数的类型签名 前面提到过,我们使用函数来筛选和映射列表,都很直观。在本节,我们将看到它们的类型签名,知道只通过此信息,就可以推断出高阶函数能做什么。当然,在一般情况下,不能从函数的类型就知道它能做什么,但对于泛型和高阶函数,例如那些用来处理列表的函数,通常是可能的。如我们前面所见的,处理泛型值的函数所做的不如单独处理值,因为,不能知道值的所有消息,因此,它们通常要翻译 2014-11-18 15:43:59 · 1380 阅读 · 0 评论 -
6.4 处理选项类型
6.4 处理选项类型 F# 中,最重要的可选值之一就是选项(option)类型。回顾一下我们在前面的章节中所看到的,选项类型能够安全地表达可能会缺失的值。这种安全性使我们在写代码时,不能轻易地假定值是存在的,当选项类型表示的值缺失时,将失败;相反,我们必须使用模式匹配,写代码要包含两种情况。在这一节,我们将学习处理选项类型两个有用的函数。 注意 我们刚才看到的处理元组的函数翻译 2014-10-31 15:46:01 · 881 阅读 · 0 评论 -
6.7.3 实现列表函数
6.7.3 实现列表函数 刚才我们看到的筛选和映射函数,没有展示如何实现,现在,我们要看一个在第三章开始创建的函数。因为所有的列表处理函数都有类似的结构,看过下面的示例以后,实现其他任何函数也是可能的。在第三章,我们写的函数,能够计算列表中的所有元素的和或积;随后,我们就意识到它可能比开始所表现的更有用:我们看到,它还能用来查找最小或最大元素。那时,我们没有讨论过泛型,因此,函数只处理翻译 2014-11-19 14:42:06 · 843 阅读 · 0 评论 -
6.7.2.1 处理列表
6.7.2.1 处理列表 我们看一个有关使用筛选和映射更大的示例,在 F# 库中的两个函数适用于各种集合类型,但我们将只用它来处理我们已经很熟悉的列表;在 C# 中,这些方法可用于任何实现了 IEnumerable 接口的集合,所以,我们将使用泛型 .NET List 类。清单 6.21 显示了我们将要处理数据的初始化。 清单 6.21 有关城市人口的数据 (C# and F#)翻译 2014-11-19 11:02:48 · 893 阅读 · 0 评论 -
6.7.3.1 在 C# 中实现 fold
6.7.3.1 在 C# 中实现 fold与 fold 有相同行为的操作,在 .NET 库中也有,但是,名字叫Aggregate(聚合)。通常,它是能够在任何集合类型上运行的扩展方法,我们也可以像 F# 函数一样使用它。清单 6.21 是我们用 C# 3.0 重写前面示例的代码。在 F# 中,我们用元组来保存在聚合过程中的状态。你也许还记得以前的几章中,我们曾提到过,C# 3.0 中的翻译 2014-11-19 15:46:12 · 1187 阅读 · 0 评论 -
6.4.3 分步分析(Evaluating)示例
6.4.3 分步分析(Evaluating)示例 能这像这样自信地使用高阶函数,是需要一些时间的,尤其是嵌套使用。我们将研究前面清单中的代码的地,通过跟踪几个样本输入。从抽象的问题“一般情况下这段代码做什么?”,到具体的问题“特定情况下这段代码做什么?”,通常可以帮助澄清真相。如果我们第一次输入一个无效的值,会发生什么。那时,从 readInput() 返回的第一个值将是 None。要翻译 2014-11-01 20:36:16 · 987 阅读 · 0 评论 -
6.4.4 实现选项类型的操作
6.4.4 实现选项类型的操作 绑定(bind)和映射(map)的实现有类似的结构,因为,两者都是依据选项值进行模式匹配的高阶函数。我们来看一看 F# 和 C# 的实现,这是在 C# 中实现函数式概念的最好示例。我们先看一下清单 6.14,这是映射操作的实现。 清单 6.14 用 F# 和 C# 实现 map 操作F# InteractiveC#翻译 2014-11-02 21:24:16 · 652 阅读 · 0 评论 -
6.8.1 映射、筛选和折叠(Mapping, filtering, and folding)
6.8.1 映射、筛选和折叠(Mapping,filtering, and folding) 映射、筛选和折叠是函数编程中最常见的操作;在处理函数式列表时,我们已经用到过,但它们还支持所有其他的集合类型(我们将在第十和十二章讨论其中一部分);这些操作并不限于集合,所有的操作都可用于处理选项类型。清单 6.25 显示了映射、筛选和折叠函数的签名类型,清单中包括了我们尚未讨论过的Optio翻译 2014-11-20 10:30:12 · 919 阅读 · 0 评论 -
6.8.2 列表的绑定操作
6.8.2 列表的绑定操作 我们只讨论了选项值的绑定(bind)操作,实际上,它是非常重要的函数式操作,我们将在第十二章介绍。清单 6.26 显示了对选项值绑定操作的类型签名,以及如果我们定义列表的绑定操作,它的类型签名。 清单 6.26 绑定操作的签名 (F#)Option.bind : ('a -> 'b option) -> 'aoption -> 'b option翻译 2014-11-20 14:31:18 · 1025 阅读 · 0 评论 -
6.3.1 处理计划列表
6.3.1 处理计划列表 在前面的示例中,因为我们想要打印新的计划,因此,使用了命令式的 for 循环;如果想要创建包含新的计划列表,可以使用 List.map 函数,就像这样: let newSchedules = List.map(fun s –> s |> mapSchedule (fun d -> d.AddDays(7.0)) )schedul翻译 2014-10-31 10:31:57 · 705 阅读 · 0 评论 -
把序列合并成字符串
把序列合并成字符串let a1 = seq ["aa";"bb"];;let a2 = seq ["aa"];;let a3 = Seq.empty;; reduce 对于空序列就不容易处理了。let b1 = a1 |> Seq.reduce(fun a b -> a + "," + b);;let b2 = a2 |> Seq.reduce(fun a原创 2012-07-28 15:21:45 · 1686 阅读 · 0 评论 -
6.3 处理计划
6.3 处理计划 在本节,我们要把上一节的技术应用到可选值。在处理元组时,我们发现使用函数,有助于处理元组中的元素;类似地,处理可选值时,同样需要使用高阶函数,对可选值中的一个或多个进行某种操作。我们接着上一章的示例,从计划类型开始,然后,看一下选项类型。在前面的章节中,我们实施了一个表示事件计划的类型。在 F# 中,使用差别联合Schedule(计划)实现,包含三种可选项;三个可选项翻译 2014-10-31 09:36:32 · 668 阅读 · 0 评论 -
6.4.1 使用 map 函数
6.4.1 使用 map 函数 我们将使用F# 库中的两个操作,因此,首先要看一下如何使用;然后,讨论如何实现,以及如何在 C# 中使用。我们已经知道,了解 F# 中函数的功能,最好的方法通常是理解类型签名。现在,我们就看一下 Option.map 的类型签名: > Option.map;;val it : (('a -> 'b) -> 'a option-> 'b optio翻译 2014-10-31 20:05:03 · 1067 阅读 · 0 评论 -
7.4 写操作
7.4 写操作 可能有多种操作我们来处理文档。我们可以使文档中的所有标题大写,或者,把多列文本合并到一个列。所有这些操作有一些共同之处,你可能会看到它们与前一章中的映射操作之间的相似性。就像映射一样,这些操作的每个都对文档进行检查,对特定部件执行一些转换,并返回一个新的文档。 另一种操作可能只返回一个不同类型的值。我们可以实现一个函数,统计文档中的字数,或将文档的全部文本翻译 2011-06-14 17:24:00 · 476 阅读 · 0 评论 -
7.4.2 使用聚合操作进行计算
7.4.2 使用聚合操作进行计算 聚合背后的概念在于我们保持一些状态,将在整个操作过程中传递。我们用一个初始状态开始,用给定的处理函数,为文档中的每个部件,计算一个新的状态。这种概念被反映在函数的签名中: val aggregateDocument : ('a -> DocumentPart -> 'a) -> 'a -> DocumentPart –> 'a翻译 2011-06-16 17:06:00 · 504 阅读 · 0 评论 -
7.3.2 用 XML 表示文档
7.3.2 用 XML 表示文档 XML 格式非常流行,完美地适合于存储分层数据,比如,我们上一节中的文档。处理 XML,对于许多现实世界的应用程序,是重要的。因此,在这一节中,我们将扩展应用程序,以支持从 XML 文件中加载文档。我们将使用 .NET 3.5 的 LINQ to XML API 来做大部分的困难工作——编写另外的 XML 解析器也没有任何意义。LINQ to XM翻译 2011-06-14 14:44:00 · 618 阅读 · 0 评论 -
6 使用高阶函数处理值
6 使用高阶函数处理值 本章介绍■ 使用元组选项和列表■ 为类型写高阶函数■ 在 F# 中使用自动泛型化■ 组合函数与偏应用 在前面的章节中,我们介绍了最常用的函数值。你已经看到这些值如何被构造,以及如何使用模式匹配来处理它们。像这样显式表示所有逻辑可能是冗长乏味的,特别是如果这个类型具有复杂的结构。 由一个或几个简单值组成的值的类型包括前一翻译 2011-05-05 14:57:00 · 530 阅读 · 0 评论 -
2.3.2.1 使用高阶函数扩展词汇
2.3.2.1 使用高阶函数扩展词汇 处理集合,最能体现高阶函数使代码更具声明性。在 C# 中,是通过扩展方法(如 Where 和 Select),使之成为 LINQ 的一部分而实现的,因为能用 LINQ 查询写的一切,都可以用把 Func(函数)委托作为参数的方法来写。在这一节,我们将用 F# 列表写同样的代码,来演示 F# 的几个重要方面。我们还没有看到真正的 F# 代码,更多地是翻译 2014-08-31 20:06:42 · 697 阅读 · 0 评论 -
6.5.1 函数组合
6.5.1 函数组合 处理函数最重要的操作,就是组合。先看一个示例是非常有用的,这个示例用元组保存(城市的)名字和人口。在清单 6.16 中,我们创建一个函数,根据人口的规模,确定是城市、镇,还是村;同时用保存在列表中的几个地方测试确定状态。 清单 6.16 处理城市信息 (F# Interactive)> let places = [("Grantchester", 552)翻译 2014-11-11 18:48:15 · 1134 阅读 · 0 评论 -
6.4.4.1 在 C#中使用选项类型
6.4.41 在 C#中使用选项类型 扩展方法能够以流畅的方式来编写使用绑定和映射的代码。由于括号中的数字可能会造成混乱,因此要注意,调用 Map 是嵌套在 lambda 函数中的,作为 Bind 的参数值: Option ReadAndAdd() { returnReadInput().Bind(n => ReadInput().Map(m=> m + n));翻译 2014-11-03 10:58:33 · 996 阅读 · 0 评论 -
6.5 使用函数
6.5 使用函数 目前为止,我们在这一章中讨论到的所有高阶函数都有类似结构,有两个参数:一个是要处理的值,另一个是指定如何处理这个值的函数。在使用函数时,值参数也可以是函数,因此,高阶函数的两个参数都可以是函数。翻译 2014-11-11 16:23:37 · 733 阅读 · 0 评论 -
6.2.1 使用函数处理元组
6.2.1 使用函数处理元组 在第三章,我们用元组来表示城市和人口。当我们想增加人口时,写的代码像这样: let (name, population) = oldPraguelet newPrague = (name, population + 13195) 这很清晰,但有点罗唆。第一行分解元组,第二行对第二个元素进行计算,然后,生成新的元组。理论上,我们可能说,对分解翻译 2014-10-30 14:01:21 · 881 阅读 · 0 评论 -
6.4.2 使用 bind 函数
6.4.2 使用 bind 函数 下一步,我们想消除外层的模式匹配,这,使用 Option.map 是做不到的,因为这个函数总是,输入为 None,转换后输出是 None,输入为 Some,转换后输出是包含其他值的 Some。在外层的模式匹配中,我们要做的事情根本不是这样,即使输入值是 Some,而如果读第二个输入失败,仍可能返回 None。这样,作为参数值的 lambda 函数指定的类型翻译 2014-10-31 21:08:41 · 783 阅读 · 0 评论 -
6.3.2 在 C# 中处理计划
6.3.2 在 C# 中处理计划 在 C# 中,我们构建的 MapSchedule 方法,类似于 F# 中的 mapSchedule 函数;另外,它有两个参数:一个是用于计算新日期的函数,另一个是原始计划。因为我们将在 C# 中使用可选值,需要 switch 块和 Tag 属性,这我们在第五章已经看到过。清单6 .9显示了完整的实现。 Listing 6.9 schedule 类翻译 2014-10-31 15:14:17 · 781 阅读 · 0 评论 -
6.2.2 C# 中处理元组的方法
6.2.2 C# 中处理元组的方法 在本节,我们将继续处理第三章的泛型 Tuple 类,添加类似于刚才在 F# 中看到的功能。清单 6.6 就是高阶函数 mapFirst 和 mapSecond 的 C# 版本。 清单 6.6 处理元组的扩展方法 (C#)public static class Tuple { publicstatic Tuple MapFirst翻译 2014-10-30 14:36:16 · 1033 阅读 · 0 评论 -
7.2.2 在窗体上显示绘图
7.2.2 在窗体上显示绘图绘图与第四章的示例类似。因为绘图需要一定的时间,我们将在内存中创建位图,绘制好文档,然后,在窗体上显示位图,而不是每次窗体失效时都绘制文档。我们先看一下非常有用的函数式编程模式,这一节就将使用。“Hole in the Middle(中间有洞)”模式[真心不知道,Hole in the Middle 是什么意思?]写代码的一个常见翻译 2014-11-25 10:08:56 · 1080 阅读 · 0 评论