如何在java中实现haskell数据类型



如果你有这些Haskell数据类型

data Mlist a = Mlist [a]
data Mordering = MLT | MEQ | MGT | MIN deriving (Eq, Show)

用java写这个最好的方法是什么?

如果您想在Java中获得仅求和类型,那么这很容易。只使用enum:

public enum Mordering {
    MLT, MEQ, MGT, MIN
}

你甚至可以免费得到等式、toString()和其他有用的东西。如果您需要仅产品类型,如Mlist,那么简单类是可行的:

public class Mlist<T> {
    public final List<T> list;
    public Mlist(List<T> list) {
        this.list = list;
    }
}

如果你需要完整的ADT(产品总和),那么事情可能会变得更复杂。

通常使用继承对此类类型进行编码。考虑Guava可选类。它相当于Haskell Maybe数据类型。它被建模为一个基类Optional和两个子类:Present(映射到Haskell Just)和Absent(映射到Nothing)。此外,基类Optional包含一些有用的工厂方法,如Optional.of(value)Optional.absent()。我认为这是你应该使用的方法。

然而,不进行模式匹配的adt值迅速降低。我认为最好不要尝试在Java中使用Haskell习语,因为这是完全不同的语言,每种语言都有自己的一套模式和技术。一些通用的概念可能在这两种语言中都有用(比如Optional/Maybe),但通常在这两种语言中有完全不同的解决问题的方法。

顺便说一句,Scala语言(也运行在JVM上)以类似的方式建模adt,通常使用abstract sealed基类和多个case classes扩展它:
abstract sealed class Optional[+T]
case class Present[+T](value: T) extends Optional[T]
case class Absent() extends Optional[Nothing]

不确定是否有最好的方法。

但是为了获得一个概念,可以这样做:通过frege编译器运行这段代码,并查看它生成的java代码。

(Frege是一种JVM语言,它试图弥补缺失的Haskell-JVM后端。Frege本质上是Haskell 2010加上更高级别的多态类型和Java互操作)

最新更新