什么是Java的奇怪重复通用模式的Haskell等价物?

时间:2011-11-18 19:08:25

标签: generics haskell types

关于java泛型的question刚出现。示例代码是:

public interface A < T extends A < T> > {

}  

链接的问题询问

Class Enum<E extends Enum<E>> ...

当我尝试阅读关于这些通用表达式的java文档时,我的眼睛瞪着它,这对我来说是希腊语。

我希望我能用Haskell等价物理解它们!

这些例子中的一个或两个在Haskell中的等价(或类似)是什么?

3 个答案:

答案 0 :(得分:10)

这个技巧用于允许接口引用具体的实现类型,例如强制参数的类型和结果的类型与实现类的类型相同:

public interface Num<A extends Num<A>> {
    A add(A other); 
}

这类似于你在Haskell中使用类型类免费获得的内容:

class Num a where
    (+) :: a -> a -> a

答案 1 :(得分:3)

这很有趣,因为这也使我感到困惑。我们试着去模拟它。我可能不会在Java中使用这个习惯用法。

如果类型A继承自类型B,则在功能域中表示存在函数B -> A。此时不要担心类和接口之间的区别;功能翻译几乎没有区别(界面只是功能记录)。让我们做一个非递归的翻译来感受它:

interface Showable {
    string show();
}

interface Describer<T extends Showable> { }

翻译成功能记录:

data Showable = Showable { show :: String }

data Describer t = Describer { showable :: t -> Showable }

如果我们忘记了向下转换,那么如果我们在Java中有一些对象,我们所知道的就是它是Showable,那么它对应于在Haskell中有一个Showable对象。从表面上看,传递Showable并传递string感觉就像是不同的东西,但它们是等价的。

extends Showable约束输入,如果我们有Describer t,那么我们知道t“是”Showable;即存在函数t -> Showable

makeDescriber :: (t -> Showable) -> Describer t
makeDescriber f = Describer { showable = f }

现在让我们来看看hammar的例子,并结合多态性。

interface Number<A extends Number<A>> {
    A add(A other); 
}

转换为功能记录

data Number a = Number {
    add :: a -> a,
    number :: a -> Number a
}

现在,如果我们有Number a,那么我们知道a“是”Number a;即有一个函数a -> Number a

java接口Number的实例成为类型上的函数。

intNumber :: Integer -> Number Integer
intNumber x = Number { add = \y -> x + y, number = intNumber }

此功能对应class Integer extends Number<Integer>。如果我们有两个整数xy,我们可以使用这种“OO”样式添加它们:

z :: Integer -> Integer -> Integer
z x y = intNumber x `add` y

通用功能怎么样:

T Add< T extends Number<T> >(T x, T y) { return x.add(y); }

(嗯是正确的Java语法?我对这种风格的体验来自C#)

记住约束成为函数,所以:

add' :: (t -> Number t) -> t -> t -> t
add' n x y = n x `add` y

当然,在Haskell中,我们看到将对象与它支持的操作捆绑在一起是多么复杂,所以我们更愿意将它们分开:

data Num t = Num { add :: t -> t -> t }

add' :: Num t -> t -> t -> t
add' n x y = add n x y

我们用实际操作实例化Num字典,例如

integerNum :: Num Integer
integerNum = Num { add = (+) }

对于后一种想法,类型类只是一些语法糖。

也许这有帮助吗?我只想看看它是如何按字面翻译的。

答案 2 :(得分:-1)

我不知道是否存在Haskell的等效语句,但Haskell确实有typeclasses。例如,Show是一个类型类,很多对象“扩展”或“实现”显示,也就是说,你可以“显示3”,“显示[1,2,3,4]”等。