Getting started with functional programming

开始函数式编程

higher-order functions-高阶函数

所有FP语言的主要特点是函数可以像普通值一样处理。它们可以存储到变量中,放入集合和结构中,作为参数传递给其他函数,并作为结果从其他函数返回。

将其他函数作为参数或返回新函数的函数称为高阶函数。

下面这两个模式在FP中很常见:


filter: (collection<T>, (T → bool)) -> collection<T>
transform: (collection<In>, (In -> Out)) -> collection<Out>

STL中的高阶函数示例

如何求一组数的平均值?


double average_score(const std::vector<int>& scores)
{
int sum = 0;
for (int score : scores)
{
sum += score;
}
return sum / (double)scores.size();
}

利用std::accumulate:



double average_score(const std::vector<int>& scores)
{
return std::accumulate(
scores.cbegin(), scores.cend(),
0
) / (double)scores.size(); // 初始值为0并求范围的和
}

在c++17中,可以实现并行计算:


double average_score(const std::vector<int>& scores)
{
return std::reduce(
std::execution::par,
scores.cbegin(), scores.cend(),
0
) / (double) scores.length();
}

也可以增加一个函数对象,改为求乘积:


double scores_product(const std::vector<int>& scores)
{
return std::accumulate(
scores.cbegin(), scores.cend(),
1,
std::multiplies<int>()
);
}

Folding

上述std::accumulate算法就是folding概念的实现。Folding将一般的迭代过程抽象成递归结构。

它首先将传递给它的初始值和集合中的第一项相加,然后将该结果与集合中的下一项进行相加,以此类推,一直重复,直到集合的末尾。如下图所示:

下面是计算一个string中'\n'的个数的算法:


int f(int pre_count, char ch)
{
return c != '\n' ? pre_count : pre_count + 1;
} int count_lines(const std::string& s)
{
return std::accumulate(
s.cbegin(), s.cend(),
0,
f
);
}

其中:

f: (R, T) -> R -- 集合元素类型为T, 初值类型为R

对于那个累加的版本,也可以这样理解,将f看作是+运算:

这种从范围的开始来处理元素的叫做left-fold。

还有right-fold,它表示从范围的结束也就是最后一个元素开始处理,一直到第一个元素。

下图是左右折叠的区别:

C++并不提供right-fold的算法,但是可以通过反向迭代器crbegin和 crend来实现相同的效果

第二章 Getting started with functional programming的更多相关文章

  1. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二章:矩阵代数

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二章:矩阵代数 学习目标: 理解矩阵和与它相关的运算: 理解矩阵的乘 ...

  2. Coursera公开课Functional Programming Principles in Scala习题解答:Week 2

    引言 OK.时间非常快又过去了一周.第一周有五一假期所以感觉时间绰绰有余,这周中间没有假期仅仅能靠晚上加周末的时间来消化,事实上还是有点紧张呢! 后来发现每堂课的视频还有相应的课件(Slide).字幕 ...

  3. [A Top-Down Approach][第二章 应用层]

    [A Top-Down Approach][第二章 应用层] 标签(空格分隔): 未分类 网络应用是计算机网络存在的理由 首先从定义几个关键的应用层概念开始 应用程序所需要的网络服务,客户和服务器,进 ...

  4. 第二章排错的工具:调试器Windbg(上)

    感谢博主 http://book.51cto.com/art/200711/59731.htm <Windows用户态程序高效排错>第二章主要介绍用户态调试相关的知识和工具.本文主要讲了排 ...

  5. Java 中的函数式编程(Functional Programming):Lambda 初识

    Java 8 发布带来的一个主要特性就是对函数式编程的支持. 而 Lambda 表达式就是一个新的并且很重要的一个概念. 它提供了一个简单并且很简洁的编码方式. 首先从几个简单的 Lambda 表达式 ...

  6. Unity文档阅读 第二章 依赖注入

    Introduction 介绍Chapter 1 outlines how you can address some of the most common requirements in enterp ...

  7. Gradle2.0用户指南翻译——第二章. 概述

    翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc本文翻译所在分支:https://github.com/msdx/gradledoc/tree/2 ...

  8. [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第二章~第七章

    在看完<Objective-C 程序设计 第6版>之后,看了一些关于iOS开发职位的面试题,发现自身基础非常是不牢,于是打算以查缺补漏的方式阅读还有一本关于Objective-C的基础书籍 ...

  9. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

随机推荐

  1. 浅谈ConcurrentDictionary与Dictionary

    在.NET4.0之前,如果我们需要在多线程环境下使用Dictionary类,除了自己实现线程同步来保证线程安全外,我们没有其他选择.很多开发人员肯定都实现过类似的线程安全方案,可能是通过创建全新的线程 ...

  2. Python3——2019年全国大学生计算二级考试

    Python语言程序设计二级重点(2019年版) 第一章 程序设计基本方法 IPO程序编写方法 :输入(input),输出(output),处理(process): Python程序的特点: (1)语 ...

  3. 算法入门——二分查找,旅行商问题,大O表示法

    一. 算法入门 博主在市面上发现了很多,很多有关书算法的书籍,但是真正能够让初学者易懂的算法书籍,只是一点点,以下我讲以 Aditya Bhargava写的一本关于算法的入门书籍,为参考,这本书非常的 ...

  4. 初识 “HTML”

    HTML 什么是HTML? ①全称:超文本标记语言②超文本:在普通的文本内容的基础上添加超链接.图片.视频等③标记语言:HTML提供一系列标签④版本:HTML 4.01 HTML声明 1.编码格式:H ...

  5. Yoshino: 一个基于React的可定制化的PC组件库

    Github: https://github.com/Yoshino-UI... Docs: https://yoshino-ui.github.io/#/ Cli-Tool: https://git ...

  6. python之三元表达式,列表|字典推导式,函数对象

    #### 三元表达式: 就是if....else...的语法糖 # -- 1) 只能解决if...else...结构,其他if分支结构都不管 # -- 2)一个分支提供一个结果: 如果一个分支提供了多 ...

  7. webpack进阶(三)

    1)CommonsChunkPlugin已经从webpack4移除,所以在用webpack进行公共模块的拆分时,会报错 Cannot read property 'CommonsChunkPlugin ...

  8. Java探针技术-retransformclasses的介绍

    retransformclasses void retransformclasses(class... classes) throws unmodifiableclassexception 重转换提供 ...

  9. 使用synchronized修饰静态方法和非静态方法有什么区别

    前言 最近被问到了这个问题,第一次回答的也是很不好,在此参考网上答案进行整理记录.供大家学习参考. Synchronized修饰非静态方法 Synchronized修饰非静态方法,实际上是对调用该方法 ...

  10. vue中nextTick的使用场景

    https://blog.csdn.net/bingqise5193/article/details/100212278