在here中所述,在Haskell,Purescript和Elm等语言中,将类型视为集合可能很强大。该工具可帮助您选择最适合您问题的数据结构。它还可以让您分析有多少种不可能的状态。
是否可以采用这个想法并将其转移到Java等程序化OOP语言中,以分析不可能的状态是否不可能?如果是这样,那看起来如何?
编辑:类型的基数为我们提供了类型可以表示的可能值的数量。在FP中,好的做法是根据数据对类型进行建模。通过计算基数,我们可以检查程序是否可以表示无效数据。如果数据结构的基数高于它应容纳的可能数据/状态的数量,则该数据结构使我们可以表示无效数据。
将此与OOP进行对比。在OOP中,我们不是在类型之后建模,而是在包含表示真实世界的属性和方法的对象之后建模。在OOP中,是否有类似的方法可以分析对象的可能实例数量以检查该对象是否可以包含无效数据?我怀疑对象可能太笼统而无法进行此类分析。
答案 0 :(得分:3)
您可以将这些概念转换为OOP语言,例如(我想)Java或C#。有些概念的翻译非常冗长,但我涵盖了here。
产品类型只是常规的Value Objects。总和类型比较棘手。
请考虑the page linked to in the OP中的Height
类型。您可以像这样在C#中Church encode:
public interface IHeight
{
T Match<T>(Func<int, T> inches, Func<float, T> meters);
}
这还需要两个实现此接口的类。
事实证明,教堂的总和类型的编码为equivalent to the Visitor design pattern,因此您还可以将 Height 总和类型定义为“访客”:
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
接口之类的东西确实应该是实现细节。但是,在这里,我用它来“展示我的作品”。您可能应该封装实现,以使没有人能获得有关实现该接口的有趣想法。这是an example of how you might do that with Either。