一个 题 刚刚提到了java泛型。示例代码是:
public interface A < T extends A < T> > {
}
一个链接的问题询问
Class Enum<E extends Enum<E>> ...
当我尝试阅读关于这些通用表达式的java文档时,我的眼睛茫然,这对我来说是希腊语。
我希望我可以用Haskell等价来理解它们!
Haskell中的一个或两个示例中的等价(或类似)是什么?
一个 题 刚刚提到了java泛型。示例代码是:
public interface A < T extends A < T> > {
}
一个链接的问题询问
Class Enum<E extends Enum<E>> ...
当我尝试阅读关于这些通用表达式的java文档时,我的眼睛茫然,这对我来说是希腊语。
我希望我可以用Haskell等价来理解它们!
Haskell中的一个或两个示例中的等价(或类似)是什么?
这个技巧用于允许接口引用具体的实现类型,例如强制参数的类型和结果的类型与实现类的类型相同,如下所示:
public interface Num<A extends Num<A>> {
A add(A other);
}
这与您在Haskell中使用类型类免费获得的类似:
class Num a where
(+) :: a -> a -> a
这很有趣,因为这也使我感到困惑。我们试着对它进行建模。我可能不会在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
,那么它对应于有一个 Showable
Haskell中的对象。在表面上,通过一个 Showable
并通过 string
感觉像是不同的东西,但它们是等价的。
该 extends Showable
约束进入,如果我们有一个 Describer t
那我们就知道了 t
“是” Showable
;即存在一种功能 t -> Showable
。
makeDescriber :: (t -> Showable) -> Describer t
makeDescriber f = Describer { showable = f }
现在让我们来看看hammar的exmaple,结合多态性。
interface Number<A extends Number<A>> {
A add(A other);
}
转换为功能记录
data Number a = Number {
add :: a -> a,
number :: a -> Number a
}
所以现在如果我们有一个 Number a
那我们就知道了 a
“是”a Number a
;即有一个功能 a -> Number a
。
java接口的实例 Number
成为一种类型的功能。
intNumber :: Integer -> Number Integer
intNumber x = Number { add = \y -> x + y, number = intNumber }
此功能对应于a class Integer extends Number<Integer>
。如果我们有两个整数 x
和 y
,我们可以使用这种“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 = (+) }
对于后一种想法,类型类只是一些语法糖。
也许这有帮助吗?我只想看看它是如何翻译的。
我不知道Haskell是否有相同的声明,但Haskell确实有 类型类。例如,Show是类型类,许多对象“扩展”或“实现”显示,也就是说,你可以“显示3”,“显示[1,2,3,4]”等。