首页 > 解决方案 > 分析 Java/OOP 中类型的基数

问题描述

在 Haskell、Purescript 和 Elm 等语言中,将类型视为集合可能很强大,如下所述此工具可帮助您选择最适合您的问题的数据结构。它还允许您分析有多少不可能的状态。

有没有可能把这个想法转移到过程 OOP 语言,比如 Java,来分析不可能的状态是不是不可能的?如果是这样,那会是什么样子?

编辑:类型的基数为我们提供了一个类型可以表示的可能值的数量。在 FP 中,好的做法是根据数据对类型进行建模。通过计算基数,我们可以检查我们的程序是否有可能表示无效数据。如果数据结构的基数高于它应该保持的可能数据/状态的数量,则数据结构允许我们表示无效数据。

将此与 OOP 进行对比。在 OOP 中,我们不是根据类型建模,而是根据包含代表现实世界的属性和方法的对象建模。在 OOP 中是否有类似的方法可以分析对象的可能实例数量以检查该对象是否可以包含无效数据?我怀疑对象可能过于笼统,无法进行此类分析。

标签: javaoophaskellfunctional-programmingtype-theory

解决方案


您可以将这些概念翻译成 OOP 语言,例如(我想)Java 或 C#。有些概念有相当冗长的翻译,但我在这里介绍其中的一些。

产品类型只是您的普通值对象。Sum 类型更棘手。

考虑OP 中链接到的页面中Height的类型。您可以像这样在 C# 中对它进行Church 编码:

public interface IHeight
{
    T Match<T>(Func<int, T> inches, Func<float, T> meters);
}

这也需要两个实现这个接口的类。

事实证明,总和类型的 Church 编码等价于访问者设计模式,因此您还可以将高度总和类型定义为访问者:

public interface IHeight
{
    T Accept<T>(IHeightVisitor<T> visitor);
}

IHeightVisitor<T>看起来像这样:

public interface IHeightVisitor<T>
{
    T VisitInches(int inches);

    T VisitMeters(float meters);
}

的实现之一IHeight应该是这个:

public sealed class Inches : IHeight
{
    private readonly int inches;

    public Inches(int inches)
    {
        this.inches = inches;
    }

    public T Accept<T>(IHeightVisitor<T> visitor)
    {
        return visitor.VisitInches(inches);
    }
}

您还需要另一个实现,即Meters类,但我将把它留作练习(提示:它看起来很像Inches)。

需要明确的是,像IHeight接口这样的东西真的应该是一个实现细节。然而,在这里,我用它来“展示我的作品”。您可能应该封装实现,这样就不会有人对实现该接口产生有趣的想法。这是一个示例,说明您如何使用Either来做到这一点。


推荐阅读