关于LSP(里氏替换原理)和子类型的问题

发布于 2024-10-21 13:58:22 字数 497 浏览 7 评论 0原文

LSP

如果 q(x) 是关于类型 T 的对象 x 的可证明属性,则 q(y) 对于类型 S 的对象 y 应该为真,其中 S 是 T 的子类型。

我可以将其改写如下:

q(x) 对于 T => 中的任何 x 都成立。 q(y) 对于 T 的任何子类型的任何 y 都成立

现在另一个陈述怎么样?

q(x) 对于 T 的任何 x 都为真,并且 q(y) 对于 S 的任何 y 都为真 => S 是 T 的亚型

这有意义吗?我们可以将它用作subtype定义吗?

LSP says that

if q(x) is a property provable about objects x of type T then q(y) should be true for objects y of type S where S is a subtype of T.

I can rephrase it as follows:

q(x) is true for any x of T => q(y) is true for any y of any subtype of T

Now what about another statement ?

q(x) is true for any x of T and q(y) is true for any y of S => S is a subtype of T

Does it make sense ? Can we use it as a definition of subtype ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浊酒尽余欢 2024-10-28 13:58:23
q(x) is true for any x of T and q(y) is true for any y of S => S is a subtype of T

答案是。该表达式的含义是可以定义 S 和 T 的共同超类型 R,然后 LSP(该名称如何成为主流的耻辱)将适用于 T->R 和 S->R。

在类型理论中,存在包含语义的类型,并且存在遵守语义的类型的实现(可能通过继承实现)。

实际上,指定类型语义(q(x) 部分)的唯一合理方法是通过实现,因此我们留下了 形式的无语义签名接口为了实现目的而继承,并实现它们喜欢的接口,但无法检查它们是否正确执行。

研究人员尝试定义形式语言来指定类型,以便工具可以检查实现是否遵守类型定义,但工作量太大,以至于将形式语言编译为可执行代码一样好。我认为这是一个永远无法解决的第二十二条军规情况。

回到你原来的问题,在允许今天所谓的“鸭子打字”的语言中,答案是不可确定的,因为任何类型的对象都可以传递给任何函数,并且如果实现了正确的签名并且结果是对的。让我解释一下......

在像 Eiffel 这样的语言中,你可以在List.append() 操作后 List.length() 必须增加。这不是 Perl、JavaScript、Python 甚至 Java 等语言的工作方式。与更严格的类型定义相比,缺乏类型严格性允许更简洁的代码。

q(x) is true for any x of T and q(y) is true for any y of S => S is a subtype of T

The answer is No. What the expression means is that a common supertype R of S and T could be defined, and that then the LSP (shame on how that name became mainstream) would hold for T->R and S->R.

In typing theory, there are types, that include semantics, and there are implementations of the types that abide to the semantics, perhaps by inheriting implementations.

In practice, the only reasonable way to specify the semantics of a type (the q(x) part) is through an implementation, so we are left with semantic-less signatures in the form of interfaces, and classes that inherit for implementation purposes, and implement the interfaces they like, with no way to check if they are doing it correctly.

Researches have tried to define formal languages to specify types, so tools can check if an implementation abides to type definitions, but the effort is so large that it would do as good to compile the formal language into executable code. It's a Catch-22 situation that I think will never be solved.

Back to your original question, in languages that allow what today is called "Duck Typing", the answer is undecidable, because an object of any type can be passed to any function, and the typing is right if the correct signatures are implemented and the result is right. Let me explain...

In a language like Eiffel you could place a postcondition on List.append() that List.length() must increase after the operation. That is not the way languages like Perl, JavaScript, Python, or even Java work. That lack of type-strictness allows for much more succinct code than stricter type definitions would.

酷到爆炸 2024-10-28 13:58:23

这没有道理;使用 and 的语句在 S 和 T 中是对称的。
但我认为你想说的是以下内容

如果对于任何命题 q 使得 q(x) 对于所有 T 类型的 x 都是可证明的,那么 q(y) 也是可证明的对于所有 S 类型的 y:,我们可以将 S 视为 T 的子类型。

我更喜欢使用数学逻辑而不是非正式英语,但如果我的定义正确的话,这就是行为子类型,现在通常称为“鸭子类型”。这是一个非常好的子类型原则,并且再次引出了这样的想法:在任何需要 T 类型值的上下文中,您可以提供一个 S 类型值,并且它是好的,因为类型 S 的值保证满足上下文期望的所有属性。

It does not make sense; your statement using and is symmetric in S and T.
But I think you meant to say the following

If it is the case that for any proposition q such that q(x) is provable for all x of type T, then q(y) is also provable for all y:of type S, than we may consider S a subtype of T.

I would prefer to use mathematical logic rather than informal English, but if I have got the definition right, this is behavioral subtyping, which these days is often called "duck typing." It's a perfectly good subtyping principle and again leads to the idea that in any context that expects a value of type T, you may instead supply a value of type S, and it's OK because the value of type S is guaranteed to satisfy all properties that are expected by the context.

伪心 2024-10-28 13:58:23

我认为不,你不能用它作为定义。此外,如果 q(x) 对于 T 的任何 x 都为真,并且 q(y) 对于 S 的任何 y 都为真
它也可能意味着 T 是 S 的子类型。

要确定哪个是哪个的子类型(假设您知道它们之间存在继承关系),您还必须了解哪个更“通用”
或者哪个比另一个更“专业”。

I think no, you can't use it as a definition. Besides if q(x) is true for any x of T and q(y) is true for any y of S
it could also mean that T is a subtype of S.

To be sure of which is a subtype of which (assuming you know that there is an inheritance relationship between them) you also have to know something about which is more "generic"
or which is more "specialized" than the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文