首先,这个问题不是 100% 特定于 Haskell,请随意评论类型类、接口和类型的一般设计。
我正在阅读LYAH - 创建类型和类型类以下是我正在寻找更多信息的段落:
Data (Ord k) => Map k v = ...
然而,在 Haskell 中,永远不要在数据声明中添加类型类约束是一个非常严格的约定。为什么?好吧,因为我们没有得到很多好处,但是我们最终会编写更多的类约束,即使我们不需要它们。如果我们在 Map kv 的数据声明中放置或不放置 Ord k 约束,我们将不得不将约束放入假定映射中的键可以排序的函数中。但是如果我们不把约束放在数据声明中,我们就不必把 (Ord k) => 放在不关心键是否可以排序的函数的类型声明中。此类函数的一个示例是 toList,它只接受一个映射并将其转换为关联列表。它的类型签名是 toList :: Map ka -> [(k, a)]。
乍一看,这似乎是合乎逻辑的——但是将类型类附加到类型上没有好处吗?如果类型类是类型的行为,那么为什么要通过使用类型(通过函数)而不是类型本身来定义行为?我认为有一些元编程可以利用它,它肯定是很好的描述性代码文档。相反,这在其他语言中会是一个好主意吗?在方法上指定对象应符合的接口是否理想,这样如果调用者不使用该方法,则对象不必符合接口?此外,为什么 Haskell 不能推断出使用 type 的函数Foo
必须引入 type 声明中标识的 typeclass 约束Foo
?是否有编译指示可以启用此功能?
我第一次阅读它时,它让人联想到“这是一个黑客(或解决方法)响应”。在第二次阅读时稍加思考,这听起来很聪明。在第三次阅读时,将其与 OO 世界进行比较,这听起来又像是一个 hack。
所以我在这里。