草庐IT

读编程与类型系统笔记03_组合

躺柒 2023-03-28 原文

1. 复合类型

1.1. 乘积类型

1.2. 组合一个或多个类型将得到一个新类型,其值为组成类型的全部可能的组合

1.3. 元组

1.3.1. 一组类型构成,通过它们在元组中的位置可以访问这些组成类型

1.3.2. 一种特殊的分组数据的方式,允许我们将不同类型的多个值作为一个值进行传递

1.3.3. 使用out参数,也就是由函数来更新实参,但这会让代码更难理解

1.3.4. 按照分量值的位置来访问值

1.3.5. 可以内联声明它们

1.3.6. 自制元组

1.4. 记录类型

1.4.1. 记录或者结构

1.4.2. 与元组类型相似,可将其他类型组合在一起

1.4.3. 为分量设置名称,并通过名称来访问值

1.4.3.1. 发生歧义的可能性较低

1.4.4. 最好定义带命名分量的记录,而不是传递元组

1.4.5. 提供一个单独的定义

1.4.5.1. 为变量提供了额外的意义

1.5. 不变量

1.5.1. 确保值的格式正确的规则

1.5.2. 一组规则规定了什么样的记录是格式正确的记录,则应该使用私有变量,并使用方法来更新这些变量,以确保规则得到实施

1.5.3. 使成员不可变

1.5.3.1. 初始化时能够确保记录是格式正确的,然后可以允许外部代码直接访问成员,因为外部代码不能修改它们

1.5.3.2. 不需要使用函数让它们保证不变量

1.5.3.3. 成员只有在构造时才会设置一次

1.5.3.4. 在不同的线程中并发访问这些数据是安全的,因为数据不会改变

1.5.3.5. 缺点:每当需要一个新值时,就需要创建一个新实例

1.5.4. 成员声明为私有,使所有访问都通过方法进行

1.5.5. 使成员不可变,并在构造函数中应用验证

2. 多选一

2.1. 结果类型的值是一个或多个成员类型的值集合中的某一个

2.2. 枚举

2.2.1. 示例:一周中的第一天

2.2.1.1. 周日

2.2.1.1.1. 美国
2.2.1.1.2. 加拿大
2.2.1.1.3. 日本

2.2.1.2. 周一

2.2.1.2.1. ISO 8601标准
2.2.1.2.2. 大多数欧洲国家

2.2.1.3. 声明一组常量值来代表一周中的各天

2.2.1.3.1. 不知道在某个模块中定义了这些常量
2.2.1.3.2. 可能自行解释这个数字
2.2.1.3.3. 采用枚举

2.3. 可选类型

2.3.1. 和类型

2.3.2. 另一个类型T的可选值

2.3.2.1. 类型T的一个值(任意值)

2.3.2.1.1. 其基本类型的值

2.3.2.2. 一个特殊值来指出不存在类型T的值

2.3.2.2.1. 不包含值

2.3.2.3. 可选类型与其基本类型不兼容

2.3.3. 自制可选类型

2.3.3.1. 封装了作为泛型实参提供的另一个类型

2.3.3.2. hasValue()方法告诉我们是否有一个实际值

2.3.3.3. getValue()返回该值

2.3.4. 用处

2.3.4.1. 大部分语言中,允许引用类型为null,来编码“没有可用值”的情形

2.3.4.1.1. 使用null容易出错
2.3.4.1.2. 很难判断一个变量什么时候可以为空
2.3.4.1.3. 什么时候不可以为空
2.3.4.1.4. 不要让null(即没有值)自身成为某个类型的一个有效的值

2.3.4.2. 将null与允许值的范围拆分开

2.3.4.3. 看到一个可选类型,就会知道它可以不包含值

2.3.4.4. 该变量不会为null

2.4. 结果或错误

2.4.1. 不用结果和错误

2.4.2. 反模式

2.4.2.1. 同时返回DayOfWeek和一个错误码

2.4.3. 自制Either类型

2.4.3.1. 和类型

2.4.3.2. TLeft

2.4.3.2.1. 存储错误类型

2.4.3.3. TRight

2.4.3.3.1. 存储有效值类型

2.4.3.4. 没有类型操作符|的语言

2.4.3.4.1. JAVA
2.4.3.4.2. C#
2.4.3.4.3. 自制
2.4.3.4.3.1. 使该值成为一个公有类型
2.4.3.4.3.2. getLeft()和getRight()方法负责转换回TLeft和TRight类型

2.4.3.5. 不能使用异常

2.4.3.5.1. 优先选择使用Either类型

2.4.4. 异常

2.4.4.1. 不能使用异常情况

2.4.4.1.1. 不能或者不希望抛出异常
2.4.4.1.2. 在进程间或线程间传播错误时
2.4.4.1.3. 当错误本身算不上异常时
2.4.4.1.3.1. 通常发生在处理用户输入的时候
2.4.4.1.4. 当调用操作系统的API,而这些API使用错误码时
2.4.4.1.5. 优先选择使用Either类型

2.5. 变体类型

2.5.1. 标签联合类型

2.5.2. 包含任意数量的基本类型的值

2.5.2.1. 使我们能够表示一个闭合类型集合的值

2.5.3. 标签指的是即使基本类型有重合的值,我们仍然能够准确说明该值来自哪个类型

2.5.4. 不要求这些类型之间存在任何关系

2.5.4.1. 不需要公共接口或基础类型

2.5.5. 自制变体

3. 代数数据类型

3.1. Algebraic Data Type,ADT

3.2. 乘积类型

3.2.1. 几乎所有编程语言都提供了定义记录类型的方式

3.2.2. 例子

3.2.2.1. 元组类型

3.2.2.2. 记录类型

3.3. 和类型

3.3.1. 相对少的主流语言为和类型提供了语法支持

3.3.2. 多个其他类型组合成为一个新类型,它存储任何一个构成类型的值

3.3.3. 允许我们在一个变量中存储来自不相关类型的值

3.3.4. 例子

3.3.4.1. 可选类型

3.3.4.1.1. Optional

3.3.4.2. 变体类型

3.3.4.2.1. Variant

3.3.4.3. Either

4. 访问者模式

4.1. 在一个对象结构的元素上执行的操作

4.2. 允许在定义新操作时,不改变其操作的元素的类

4.3. 双分派机制

4.3.1. 给定IDocumentItem,调用正确的accept()方法

4.3.2. 给定IVisitor实参,执行正确的操作

4.3.3. 经典实现

4.3.4. 把职责(如屏幕渲染和阅读)拆分到单独的组件(访问者)

4.3.5. 并把职责从文档项中抽象出来

4.4. 面向对象实现需要使用一个公共基类或接口

4.4.1. 扩展性不太好

4.4.2. 不同地方混搭不同的类型

4.4.2.1. 会有大量无法重用的接口或基类

4.5. 正确函数应用到变体的访问者函数

4.5.1. 更好地进行职责划分的一种访问者模式实现

4.5.2. 变体和访问者是泛型类型,可以在不同的问题域中重用

4.5.3. 访问者只负责处理

4.5.4. 文档项只负责存储域数据

4.5.5. 类型之间并没有关系

4.5.6. 不是经典的OOP实现

4.5.6.1. 优势:域对象与访问者完全分离开

4.5.7. 和类型

4.5.7.1. 提供了一种简单、干净的方式

4.6. 将易错代码封装到一个可重用的组件中

4.6.1. 这是降低风险的一种好方法

有关读编程与类型系统笔记03_组合的更多相关文章

  1. 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类的两个特殊实例的字符串

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

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

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

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

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

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

  5. 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

  6. 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

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

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

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  10. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

随机推荐