haskell - 你能做些什么对 Haskell 类型类有用?

标签 haskell

我知道类型类对于组织数据和类型检查等非常有用,但是除了前奏中已经包含的内容之外,是否需要定义自己的类?

在几乎任何情况下,只要定义一个数据或新类型,就可以得到几乎相同的效果。使用内置的“Ord”、“Eq”、“Show”和其他似乎足以做任何你想做的事情。

当我在 Haskell 中查找类的项目时,我得到了很多这样的示例类:

class Foo a where
    bar :: a -> a -> Bool

如果有理由使用类型类,是否有人有一个好的项目供初学者练习使用它们或一些好的表单指南?

最佳答案

与参数多态性相反,类型类提供临时多态性:不需要为每种类型以相同的方式(或根本不)定义函数。此外,它以开放的方式这样做:当您定义类本身时,您不需要枚举实现该类的所有类型。

非标准类型类的一些突出示例是各种 MonadFoo mtl 提供的类(class)(单子(monad)变压器库),ToJSONFromJSONaeson 提供图书馆和 IsString ,这使得 OverloadedString扩展工作。

如果没有类型类,您可以定义一个适用于单个参数类型的函数

foo :: Int -> Int

或适用于所有参数类型的一种
foo :: a -> Int

对某些类型的子集起作用的唯一方法是使用 sum 类型
foo :: Either Int Bool -> Int

但您不能稍后定义 foo对于 Float不改变 foo 的类型本身
foo :: Either Int (Either Bool Float) -> Int

或者
data IntBoolFloat = T1 Int | T2 Bool | T3 Float
foo :: IntBoolFloat -> Int

要么使用,要么使用起来很麻烦。

类型类允许您一次使用一种类型,并允许您以非侵入方式添加新类型。
class ToInt a where
    foo :: a -> Int

instance ToInt Int where foo = id
instance ToInt Bool where
    foo True = 1
    foo False = 2
instance ToInt Float where
    foo x = 3  -- Kind of pointless, but valid
ToInt 的一个实例可以在任何地方定义,尽管实际上最好在定义类本身的模块中定义它,或者在定义实例化类型的模块中定义它。

在底层,方法(由类型类定义的函数)本质上是类型到函数的映射。 TypeApplications扩展使这一点更加明确。例如,以下是等价的。
foo True == 1
foo @Bool True == 1 -- foo :: ToInt a => a -> Int, but foo @Bool :: Bool -> Int

关于haskell - 你能做些什么对 Haskell 类型类有用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57310715/

相关文章:

haskell - 如何防止GHC中的共享?

haskell - 删除文件(如果存在)

haskell - 为什么 Haskell monadic 是左结合的?

haskell - 如何结合数据组合和 monad 转换器

list - Haskell - 连接字符串列表

haskell - Haskell 如何从文件中读取 S 表达式?

haskell - Haskell monad 不强制执行的分类单子(monad)的身份是什么?

haskell - 数据类型中严格字段的​​优势

performance - Haskell 性能——拓扑排序不够快

Haskell 无法统一类型​​实例方程