Type Class与代数数据类型的区别及相关概念界定疑问
问题解答
1. Fantasy-land将Setoid、Ord、Semigroup归为ADT的合理性
在Haskell这类传统静态函数式语言里,Setoid(对应Eq)、Ord、Semigroup都是类型类,绝非ADT。但Fantasy-land是针对JavaScript动态特性设计的规范,它对"ADT"的定义是带有代数约束的类型,和传统ADT(复合数据类型)的概念存在差异。
这些类型并不是由其他基础类型复合而成,而是要求类型必须实现特定的方法契约:
- Setoid:必须实现
equals方法,满足自反性、对称性、传递性三大相等性规则 - Ord:基于Setoid,额外要实现
lte(小于等于)方法,符合全序逻辑 - Semigroup:实现
concat方法,满足结合律
所以Fantasy-land的归类是JS生态下的特殊定义,不能直接套用传统函数式编程的ADT概念。
2. Either和Maybe是否属于类型类?
不是。Either和Maybe是正经的代数数据类型(ADT):
- Either是和类型,由
Left a和Right b两个分支复合而成 - Maybe是可选类型,由
Just a和Nothing两个分支复合而成
Functor、Monad才是类型类——Either和Maybe可以实现这些类型类的契约(比如Either实现map方法就符合Functor的规则),但它们本身是具体的数据结构,而非行为抽象的类型类。
3. Eq和Functor的定位
- Eq(对应Fantasy-land的Setoid):纯纯的类型类。它定义了"能判断相等性"的行为规范,各种具体类型(比如Maybe、Either、数字)都可以实现这个规范,但Eq本身不是具体的数据类型,更不是ADT。
- Functor:也是类型类。它定义了"可映射"的行为(
map方法),要求满足两大函子定律:map(id) = id、map(f·g) = map(f)·map(g)。像Maybe、Either这类ADT可以实现Functor的契约,但Functor本身不是ADT。
一句话总结:类型类是行为抽象,ADT是具体数据结构;ADT可以去实现类型类的规则,但两者分属不同范畴。
内容的提问来源于stack exchange,提问作者PunGy
相关产品推荐
相关产品推荐

