为什么要避免子类型? [英] Why avoid subtyping?

查看:139
本文介绍了为什么要避免子类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经在斯卡拉社区看到很多人建议避免类似瘟疫的分类。什么是反对使用子类型的各种原因?什么是替代品?

解决方案

类型决定组合的粒度,即可扩展性。 b $ b

例如,一个接口,例如可比较的是,它将平等和关系运营商相结合(从而混合)。因此,不可能仅仅构造一个相等或相关接口。



通常,知识形成将不存在



函数组合是子类型的完全替代,因为函数的输入可以代替它的输出,也就是说,任何输出类型被预期的地方,输入类型可以被替换,通过包装在函数中呼叫。但是组合并不构成subtyping的双重约定 - 访问函数输出的接口,不访问函数的输入实例。



不必维护 future (即无界)不变量,因此可以是可扩展的和可确定的。如果子类型可证明是可确定的,则子类型可以更强大,因为它保持这种双重合约,例如,一个函数可以对不可变的超类型列表进行排序,可以在子类型的不可变列表上进行操作。

因此,结论是枚举每个类型的所有不变式),使这些类型正交(最大化组合的粒度),然后使用函数合成来完成那些不变量不会正交的扩展。因此,子类型仅适用于对超类型接口的不变量进行建模的情况,并且子类型的附加接口可证明与超类型接口的不变量正交。因此,接口的不变式应该是正交的。



分类理论为模型提供规则每个子类型的不变量,即Functor,Applicative和Monad,其中保留提升类型的函数组合,即请参阅前面提到的列表子类型的例子。


I have seen many people in the Scala community advise on avoiding subtyping "like a plague". What are the various reasons against the use of subtyping? What are the alternatives?

解决方案

Types determine the granularity of composition, i.e. of extensibility.

For example, an interface, e.g. Comparable, that combines (thus conflates) equality and relational operators. Thus it is impossible to compose on just one of the equality or relational interface.

In general, the substitution principle of inheritance is undecidable. Russell's paradox implies that any set that is extensible (i.e. does not enumerate the type of every possible member or subtype), can include itself, i.e. is a subtype of itself. But in order to identify (decide) what is a subtype and not itself, the invariants of itself must be completely enumerated, thus it is no longer extensible. This is the paradox that subtyped extensibility makes inheritance undecidable. This paradox must exist, else knowledge would be static and thus knowledge formation wouldn't exist.

Function composition is the surjective substitution of subtyping, because the input of a function can be substituted for its output, i.e. any where the output type is expected, the input type can be substituted, by wrapping it in the function call. But composition does not make the bijective contract of subtyping-- accessing the interface of the output of a function, does not access the input instance of the function.

Thus composition does not have to maintain the future (i.e. unbounded) invariants and thus can be both extensible and decidable. Subtyping can be MUCH more powerful where it is provably decidable, because it maintains this bijective contract, e.g. a function that sorts a immutable list of the supertype, can operate on the immutable list of the subtype.

So the conclusion is to enumerate all the invariants of each type (i.e. of its interfaces), make these types orthogonal (maximize granularity of composition), and then use function composition to accomplish extension where those invariants would not be orthogonal. Thus a subtype is appropriate only where it provably models the invariants of the supertype interface, and the additional interface(s) of the subtype are provably orthogonal to the invariants of the supertype interface. Thus the invariants of interfaces should be orthogonal.

Category theory provides rules for the model of the invariants of each subtype, i.e. of Functor, Applicative, and Monad, which preserve function composition on lifted types, i.e. see the aforementioned example of the power of subtyping for lists.

这篇关于为什么要避免子类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆