haskell类型
Haskell 类型
在Int等默认内置类型外,haskell支持创建自定义的类型系统.这里说的类型更像c中的struct和class,可以有多个类型和不同取值的组合.对于稍微复杂的系统,使用自定义和库里的类型是不可避免的
数据类型定义
基础数据类型
| 1 | data Bool = False | True | 
data 关键字用于定义新的数据类型,Bool 是类型名,False 和 True 是值构造器,分别表示布尔值的两种可能性.| 表示或.
注意:类型名和值构造器的首字母必须大写.
- 数据类型:Haskell 中的数据类型定义类似于枚举,表示一个类型的所有可能值.
- 值构造器:它们是构造类型值的方式,可以理解为是某种“标签”,标明当前值属于哪个分支.
eg:
| 1 | data Shape = Circle Float Float Float | Rectangle Float Float Float Float | 
- Circle和- Rectangle是值构造器,同时也是函数,接受- Float类型参数.
- 类型 - Shape表示几何图形.
- Circle Float Float Float:第一个和第二个- Float表示圆心的坐标,第三个- Float表示半径.
- Rectangle Float Float Float Float:四个- Float分别表示矩形对角线两点的坐标.
我们可以基于 Shape 定义函数,例如计算面积:
| 1 | surface :: Shape -> Float | 
自动派生类型
可以使用 deriving 自动生成某些类型类的实例:
| 1 | data Shape = Circle Float Float Float deriving (Show) | 
- deriving:Haskell 提供了自动派生功能,能够为常见的类型类生成默认实现.这允许- Shape类型的值可以直接使用print的方法输出,就行Int和Char一样.可以理解为oop中的子类
嵌套数据类型
| 1 | data Point = Point Float Float deriving (Show) | 
通过组合类型 Point,Shape 描述了更复杂的几何形状.
- 组合数据类型:Point是一个更抽象的数据类型,用于表示二维空间中的点.Shape使用Point类型参数化了几何形状,提升了表达能力.
类型参数与泛型
| 1 | data Maybe a = Nothing | Just a | 
Maybe 是带类型参数 a 的类型构造器,可表示“可能存在”或“不存在”的值,例如 Maybe Int 或 Maybe String.
- 类型参数:a是一个占位符,表示可以接受任何类型.
- 用途:Maybe类型常用于处理可能失败的计算,类似于其他语言中的Optional或Nullable.
泛型向量定义
| 1 | data Vector a = Vector a a a deriving (Show) | 
此定义适用于不同类型的三维向量.
- 泛型参数 a:表示向量的分量类型,例如可以是Int或Float.
- vplus函数:定义了两个向量的逐元素加法.
类型类与实例
类型类类似于接口,定义了一组通用行为.例如,Eq 类型类定义了相等性:
| 1 | class Eq a where | 
- 类型类:类似于接口,描述了一组类型支持的操作.
- 默认实现:Eq中提供了==和/=的默认实现,减少了实例化类型类的重复工作.
为数据类型实现类型类
以交通信号灯为例:
| 1 | data TrafficLight = Red | Yellow | Green | 
- instance:用于为具体的数据类型定义类型类的实现.
- 模式匹配:通过具体值的匹配,实现 TrafficLight的Eq实例.
常见类型类
- Eq: 支持相等性判断.
- Ord: 支持排序.
- Show: 支持打印.
- Read: 支持字符串解析.
- Enum: 支持枚举.
- Bounded: 支持上下界.
eg:
| 1 | data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | 
- 多重派生:Day同时派生了多个类型类实例,使其支持相等性比较、排序、打印等操作.
- 范围操作:Bounded和Enum的实例使得可以生成枚举范围.
Functor 与递归数据结构
Functor 类型类
Functor 提供了一种将函数应用于容器内值的方式:
| 1 | class Functor f where | 
- f是类型构造器:它接受一个类型参数,例如- Maybe或列表.
- fmap:表示将函数应用到容器(如- Maybe或树)中的每个元素.
以 Maybe 为例:
| 1 | instance Functor Maybe where | 
- Maybe的 Functor 实例:定义了如何将函数映射到- Maybe类型的值上.
- 用途:允许对容器中的值进行函数操作,而不需要显式解包.
递归数据结构:树
| 1 | data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show) | 
通过递归方式定义操作:
| 1 | treeInsert :: (Ord a) => a -> Tree a -> Tree a | 
- 递归定义:通过递归调用 treeInsert,构造或更新树结构.
- 平衡性:尽管此处未实现平衡逻辑,但该方法可用于构建基本的二叉搜索树.更复杂的平衡树在haskell中的实现机制需要多加考虑,因为haskell中对于已有数据的修改本质都是创建新副本,使得整个修改过程构成一个巨大的可持久化结构,关于空间使用还需注意