Rust和Haskell中的类型类的特性有什么区别?
Rust中的特性看起来至少与Haskell中的类型类似,但是我看到人们写道他们之间有一些区别。 我很想知道这些差异究竟是什么。
在基本层面上,没有太大的区别,但他们仍然存在。
Haskell将typeclass中定义的函数或值描述为“方法”,正如特征描述它们所包含的对象中的OOP方法一样。 然而,Haskell处理这些问题的方式不同,将它们视为单独的值,而不是将它们固定为一个对象,因为OOP会导致他们这样做。 这是关于最明显的表面水平差异。
直到最近,Rust才能做到的一件事是高级类型的特征,比如臭名昭着的Functor
和Monad
类型特征。
这意味着Rust特征只能描述通常所说的“具体类型”,换句话说,没有一个通用的论点。 然而,Haskell可以创建高阶类型类,它们使用类似于高阶函数使用其他函数的类型,用一个来描述另一个函数。 我们无法实现Rust中前面提到的类型类型,因为它不支持这个在Haskell中被视为基本的特性,甚至是不可或缺的特性。 值得庆幸的是,最近这项工作已经实施了相关的项目。*但这不是惯用的Rust,通常被认为是'黑客'。
正如在评论中所说的那样,GHC(Haskell的主编译器)支持类型类的更多选项,包括多参数类型(即涉及的多种类型)类型类和函数依赖关系,这是一个可爱的选项,允许进行类型级计算,并导致打字家庭。 据我所知,Rust虽然没有funDeps或类型的家庭,但它可能在未来。
总而言之,尽管特质和类特化表面看起来可能相当,但在考虑到众多特性时,它们在深度比较时确实存在很多差异。
*在附注中,斯威夫特尽管有特质,却没有这种更高级的打字机制。 未来更新的语言,也许?
†关于Haskell的类型类(包括更高类型的类)的一篇很好的文章可以在这里找到,Rust的特性同样适用于这里,但不幸的是已经过时了。
Rust的“特征”类似于Haskell的类型类。
与Haskell的主要区别在于,特征仅用于带有点符号的表达式,即形式为a.foo(b)的表达式。
Haskell类型类扩展到更高阶的类型。 铁锈特征仅仅不支持更高阶的类型,因为它们在整个语言中都是缺失的,即它不是特征和类型类的哲学差异
我认为当前的答案忽略了Rust特征和Haskell类型之间最基本的区别。 这些差异与特征与面向对象语言结构有关的方式有关。 有关这方面的信息,请参阅Rust书。
特质声明创建特质类型 。 这意味着你可以声明这种类型的变量(或者说,类型的引用)。 您还可以将trait类型用作函数,结构字段和类型参数实例的参数。
只要引用对象的运行时类型实现特征,运行时特征引用变量就可以包含不同类型的对象。
// The shape variable might contain a Square or a Circle,
// we don't know until runtime
let shape: &Shape = get_unknown_shape();
// Might contain different kinds of shapes at the same time
let shapes: Vec<&Shape> = get_shapes();
这不是类型类的工作方式。 他们没有创建类型 ,所以你不能用类名声明变量。 Type类作为类型参数的边界 ,但类型参数必须用具体类型实例化,而不是类型本身。
您不能拥有实现相同类型类的不同类型的不同事物的列表。 (相反,Haskell使用存在类型来表达类似的东西。)
特征方法可以动态分派 。 这与上面项目符号中描述的内容密切相关。
动态分派意味着对象参考点的运行时类型用于确定通过引用调用哪个方法。
let shape: &Shape = get_unknown_shape();
// This calls a method, which might be Square.area or
// Circle.area depending on the runtime type of shape
print!("Area: {}", shape.area());
Haskell再一次使用存在类型。
结论是
在我看来,特质与类型类本质上是相同的概念。 另外,它们还具有面向对象接口的功能。
(Haskell的类型类更加先进,因为Haskell具有例如高级类型和扩展类似多参数类型类,但我认为它们本质上是相同的。)
链接地址: http://www.djcxy.com/p/43473.html上一篇: What is the difference between traits in Rust and typeclasses in Haskell?