草庐IT

读编程与类型系统笔记05_函数类型

躺柒 2023-03-28 原文

1. 策略模式

1.1. 在运行时从一组算法中选择某个算法

1.1.1. 封装一组算法

1.1.2. 在运行时使用其中一个算法

1.2. 把算法与使用算法的组件解耦

1.3. 面向对象实现

1.3.1. 惯例实现

1.3.2. IStrategy接口

1.3.3. ConcreteStrategy1类

1.3.4. ConcreteStrategy2类

1.3.5. 通过IStrategy接口使用算法的Context类

1.3.6. 常见原因

1.3.6.1. 依赖接口的方法

1.3.6.2. 设计模式在20世纪90年代流行起来

1.3.6.3. 当时并不是所有主流编程语言都支持一等函数

1.4. 函数式实现

1.4.1. Context类

1.4.2. concreteStrategy1()函数

1.4.3. concreteStrategy2()函数

1.4.4. 更简洁的实现

2. 函数的类型

2.1. 函数的签名

2.2. 函数的实参类型和返回类型决定了函数的类型

2.3. 两个函数接受相同的实参,并返回相同的类型

2.3.1. 函数具有相同的类型

3. 一等函数

3.1. 将函数赋值给变量,并像处理类型系统中的其他值一样处理它们

3.2. 一等公民

3.2.1. 赋予它们与其他值相同的权利

3.2.2. 有类型

3.2.3. 可被赋值给变量

3.2.4. 可作为实参传递

3.2.5. 可被检查是否有效

3.2.6. 在兼容的情况下可被转换为其他类型

4. 状态机

4.1. 有一组状态,以及状态之间的转移

4.2. 以给定状态(也叫作开始状态)开始;如果满足特定条件,就能转移到另外一个状态

4.3. 经典的状态机

4.3.1. 将状态集合定义为一个枚举

4.3.2. 跟踪当前的状态

4.3.3. 使用覆盖所有可能状态的switch语句来获得所希望的行为

4.3.4. 使用switch语句的状态机

4.3.4.1. 缺点

4.3.4.1.1. 状态没有与想要在每种状态下运行的逻辑联系在一起
4.3.4.1.2. 状态和转移作为一个单独的枚举进行维护,有不同步的风险

4.4. 使用函数的状态机

4.4.1. 状态完全是由一个函数来表示

4.4.2. 不需要单独跟踪状态

4.4.2.1. 状态与处理逻辑保持同步

4.4.2.2. 去掉了枚举

4.4.2.3. 去掉状态属性

4.4.2.4. 去掉处理转交给合适方法的switch语句

4.4.3. 更简洁的实现

4.4.3.1. 缺点:每种状态关联更多信息要显式声明可能的状态和转移

4.5. 使用和类型的状态机

4.5.1. 把每种状态表示为一个单独的类型

4.5.2. 整个状态机表示为可能状态的一个和类型

4.5.3. 把状态机分解到类型安全的组件中

4.5.4. 比依赖函数的实现更长

4.5.4.1. 优点:允许我们在每种状态中添加属性和成员,把它们组合在一起

4.6. 不使用switch语句的状态机

5. 延迟计算

5.1. 可以传递函数而不是传递实际的值,并在需要值的时候调用这些函数

5.2. 纯粹的面向对象结构可以实现,但是代码比函数式多得多

5.3. 许多函数式编程语言共有的特征

5.3.1. 所有内容都是尽可能晚计算的

5.4. lambda

5.4.1. 匿名函数

5.4.2. 一次性函数

5.4.2.1. 只会引用这种函数一次,所以为其命名就成了多余的工作

6. 立即计算

6.1. 立即得到并传递值,即使我们在以后决定丢弃该值

6.2. 命令式编程语言(如TypeScript、Java、C#和C++)

7. 一阶函数

7.1. 普通函数

7.2. 接受一个或多个非函数实参并返回一个非函数类型的“标准”函数

8. 高阶函数

8.1. 定义:把所有接受或返回其他函数的函数

8.1.1. 二阶函数

8.1.1.1. 接受一个一阶函数作为实参或者返回一个一阶函数的函数

8.1.2. 三阶函数

8.1.2.1. 接受二阶函数作为实参或者返回二阶函数的函数

8.2. 基础算法

8.2.1. map()

8.2.1.1. 给定某个类型的值的一个集合

8.2.1.2. 对其中每个值调用一个函数

8.2.1.3. 返回结果集合

8.2.1.4. 自制map

8.2.1.4.1. 一个T数组和一个函数作为实参
8.2.1.4.2. 该实参函数接受项目T作为实参,并返回U类型的一个值
8.2.1.4.3. 函数把结果添加到一个U数组中

8.2.1.5. C# System.Linq Select()

8.2.1.6. Java java.util.stream map()

8.2.2. filter()

8.2.2.1. 给定一个数据项集合和一个条件

8.2.2.2. 过滤掉不满足该条件的数据项

8.2.2.3. 返回满足该条件的数据项集合

8.2.2.4. 自制filter

8.2.2.4.1. 输入数组的类型为T
8.2.2.4.2. 过滤函数接受T作为实参,并返回boolean结果
8.2.2.4.2.1. 谓词

8.2.2.4.2.1.1. 接受一个实参并返回一个boolean的函数

8.2.2.4.3. 返回过滤后的输出

8.2.2.5. C# System.Linq Where()

8.2.2.6. Java java.util.stream filter()

8.2.3. reduce()

8.2.3.1. 将所有集合项合并为一个值

8.2.3.1.1. 创建一个初始值
8.2.3.1.2. 遍历集合并把每个数据项与累积项合并,不断累积结果
8.2.3.1.3. 遍历完集合后返回累积结果

8.2.3.2. 自制reduce

8.2.3.2.1. 泛型函数
8.2.3.2.1.1. 实参为T数组
8.2.3.2.1.2. 实参T类型的一个初始值

8.2.3.2.1.2.1. 需要处理输入数组为空的情况

8.2.3.2.1.3. 实参一个接受两个T类型的实参并返回T类型的结果

8.2.3.3. C# System.Linq Aggregate()

8.2.3.4. Java java.util.stream reduce()

8.2.3.5. 没有幺半群时

8.2.3.5.1. 考虑初始值是什么
8.2.3.5.2. 在哪个方向上进行缩减

8.3. 抽象代数

8.3.1. 处理集合以及集合上的操作

8.3.2. T值集合上的一个操作

8.3.2.1. 类型T的一个操作接受两个T作为实参,并返回另一个T,即(T, T) => T

8.3.3. 单位元

8.3.3.1. T的一个元素id

8.3.3.2. 操作op(x, id) == op(id, x) == x

8.3.3.3. id与其他任何元素合并起来,并不会改变其他元素

8.3.3.3.1. 操作是加法时,单位元是0
8.3.3.3.2. 操作是乘法时,单位元是1
8.3.3.3.3. 操作为字符串连接时,单位元是“”(空字符串)

8.3.4. 相关性

8.3.4.1. 操作的一个属性

8.3.4.2. 对元素序列应用操作的顺序并不重要,因为最终结果是相同的

8.3.4.3. op(x, op(y, z)) == op(op(x, y), z)

8.3.4.3.1. 加法
8.3.4.3.2. 乘法
8.3.4.3.3. 减法
8.3.4.3.4. 连接两个字符串的首字母

8.3.5. 幺半群(monoid)

8.3.5.1. 有一个单位元

8.3.5.2. 具有相关性

8.3.5.3. 不要求提供初始值

8.3.5.3.1. 在集合为空时默认使用单位元

8.3.6. 半群(semigroup)

8.3.6.1. 没有单位元

8.3.6.1.1. 把初始值放到第一个元素的左边或者最后一个元素的右边很重要

8.3.6.2. 具有相关性

有关读编程与类型系统笔记05_函数类型的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  3. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  4. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  7. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  8. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  9. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  10. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

随机推荐