Raf*_*ini 20 haskell standard-library typeclass
我见过很多人抱怨标准库中的某些类型类,比如"Monad应该要求Functor",甚至"Monad应该要求Applicative","Applicative应该要求Pointed","Num不应该要求Show"等等,所以,我有一些问题:
是否存在类型类依赖关系树具有社区感知的"缺陷"的方式的论证,或者这仅仅是历史上事情的结果?
这种变化有多大程度会破坏现有代码?
是否有基本类型类的替代实现(特别是箭头,monad,applicative等等)实现"正确"的类依赖关系?
C. *_*ann 18
除了向后兼容性之外,由于Haskell处理类型类的相当简单的方式,因此存在一些(主要是装饰性的,但很难处理)问题:
没有向上隐含的定义:Monad
完全由just pure
和(>>=)
; fmap
并且(<*>)
可以用这些来写.在"适当的"层次结构中,每个实例都需要写出来.在这种情况下并不是太糟糕,但随着粒度的增加,每个添加一些小功能的实例数也会增加.如果类定义可以根据自己的函数提供超类函数的默认实现,那么它将大大简化事情,因此(>>=)
完全包含超类中多个函数的函数可以作为整个相关层次结构的定义.
上下文膨胀:只要有一个"理由"是Num
需要Show
和Eq
,这是因为数字印刷和比较平等是很常见的.这些是严格正交的,但是将它们分开意味着完成所有三件事的函数现在必须在它们的类型中指定所有三个类.这在技术上是一件好事,但同样,随着粒度的增加,函数类型签名也会增加.
单片依赖:类型类及其超类的层次结构可以添加到但不能更改或替换.如果一段代码感觉需要替换它自己版本的某些常见类型 - 比如说,使用这样的东西来替换Monad
- 那么层次结构就会被切断; Monad
必须在某种程度上手动提供与使用其他定义的代码的兼容性,并且即使仅依赖于两个定义共享的行为子集,也必须重新实现或转换构建在另一个定义之上的任何类型类.
没有明确正确的层次结构:如上所述,可以在类的粒度中做出选择.例如,Pointed
确实需要存在,还是仅仅Applicative
足够?这里真的没有答案是普遍理想的,而且不应该有.
我怀疑通过首先处理上述问题可以更好地解决现有类型类的问题,之后更换类型类将不那么痛苦,甚至只是一种形式.例如,@ luqui提到的类型类同义词提议将是朝着这个方向迈出的重要一步.
最近在Haskell-prime列表上对此进行了讨论,我认为从那里发生的事情是,为了实现等级变更,需要首先实施JónFairbairn的提案,这将解决非常非常重要的问题1 of @ camccan的列表:类型类可以为其超类定义提供默认实现.我不知道该提案的任何实施,甚至中途正式规范.
键入类同义词修复点#2,上下文膨胀.请注意,如果您使用得很好UndecidableInstances
(并且GHC在每次推断类型时都扩展同义词......),您已经可以这样做了.
对于#4,对#1和#2进行了不错的修复解决了大多数实际问题.如果它不仅仅是粒度问题(答案是同义词,包括为整个类型同义词编写实例),但是可以选择多个可能的超类,那么事情变得更加毛茸茸,我认为当涉及到数学Num
时,这就出现了-等级.对此的解决方案(替代子类?)在此过程中有很大的机会解决#3.
但是,在任何情况下,我认为努力是值得的,因为对Haskell进行这些更改(不仅仅是对层次结构)肯定会使Haskell和Haskell代码更加灵活,从而在nay-sayer之下拉出来.目前的论点.
归档时间: |
|
查看次数: |
1205 次 |
最近记录: |