繁体   English   中英

什么是Scala的“强大”类型系统?

[英]What is Scala's “powerful” type system?

讨论Scala时,类型系统始终被视为主要功能之一。 它被称为强大的,并且是语言名字对象的主要原因(Scala是“可伸缩语言”的缩写)。 有人可以解释Scala键入的工作原理/为什么这个独特的,以及它如何有助于语言的可扩展性?

我不认为现有的答案是恰当的。 Scala有很多便利,但它们与类型系统无关,因为它们与类型有关。 事实上,类型推断与类型系统的力量直接冲突 - 如果它不那么强大,可以有完整的类型推断(如在Haskell中)。

所以,

  • Scala有成员的课程。 (很明显,但我想在这里详尽无遗。)
  • scala类的方法(“def”)成员可以具有零个或多个参数列表,每个参数列表可以具有零个或多个参数,最后一个参数可以是vararg。
  • 参数可以通过值或名称传递。
  • 参数具有名称,可能具有默认值。
  • Scala有“var”和“val”成员(实际上也是方法)。
  • 斯卡拉有“懒惰的”成员。
  • Scala具有“类型”成员(类型别名),可以指定为固定类型或类型边界。
  • Scala有抽象类和成员(以上所有成员都可能是抽象的)。
  • Scala有内部类,特征和对象(Scala的内部类与Java不同)。
  • Scala的成员,加上内部的东西,可能会被覆盖。
  • Scala具有类型继承。
  • Scala具有特征,提供类型线性化的多重继承。
  • Scala的traits的方法成员可能具有抽象覆盖(可堆叠,类似方面的覆盖)。
  • Scala有单例类型。
  • Scala具有伴随类/对象(与范围相关)。
  • Scala拥有私人,受保护和公共范围的课程,特征,单身人士和成员。
  • Scala的私有和受保护范围可以限制为任何封闭的包,类,特征或单例,加上“this”。
  • Scala有自我类型。
  • Scala具有类型参数。
  • Scala的类型参数可以是共变量和反变量,也可以是不变量。
  • Scala具有类型构造函数。
  • Scala具有更高阶的类型。
  • Scala具有存在类型。
  • Scala具有结构类型。
  • Scala具有隐式参数。
  • Scala有函数类型,因为它们只是一个类加上语法糖,我不认为它属于这个列表。 另一方面,函数类型是视图边界的一部分,所以也许它可以。
  • Scala有一个顶级(几乎每个人)和一个底部(像其他静态类型的fp语言)。
  • Scala的“单位”是一种具有价值的类型(与其他地方的“无效”相对)。

接下来,有一些与Scala的含义相关的功能,这是它们的优点。

  • Scala具有视图边界,这是一个隐式参数,其作用类似于另一种类型绑定。
  • Scala有上下文counds,一个隐含的参数,就像另一个绑定。
  • 一般而言,可以组合隐式参数和类型推断以在类型参数上构造任意复杂证明。

与上一个注释,implicits和类型推断相关联,使得Scala的类型系统turing完整 也就是说,您将任意程序编码为类型,编译器将在编译时“运行”。 这里证明,通过SKI微积分,在类型中有一个“越野车”无限循环作为进一步的演示。

上面的功能列表相当大,令人印象深刻。 然而,Scala结合implicits和类型推断以在编译时生成静态证明(例如视图边界和上下文边界)的方式使得Scala的类型系统是唯一的。 AFAIK,没有其他语言可以做到这一点,尽管肯定有其他语言通过其他方式提供证明功能。

Scala的类型系统优于Java的一些优点:

  1. 在许多情况下可以推断出类型,而不是明确指定。 这更方便,但它促进了使用复杂的类型。

    val map = new Map[String, (String, String)]()

    代替

    Map<String, Tuple<String, String>> map = new HashMap<String, Tuple<String, String>>()

  2. 功能可以在类型系统中简单表达。 如果你想看看它有多强大,可以考虑将番石榴库作为Java的解决方案。 这是令人难以置信的约束和冗长(但仍然有用)。

    val double = (x: Int) => x * 2

    而不是(使用番石榴)

    Function<Integer, Integer> double = new Function<Integer, Integer>() { @Override public Integer apply(Integer value) { return value * 2; }}

  3. 元组是Scala中的一种类型,它绕过了Java只能返回单个值的问题。

  4. Scala支持类型方差,因此当Cat是Thing的子类型时(或当反向关系成立时),您可以指定SomeObject是SomeObject的子类型。 在java中, 泛型不是协变的 ,这通常是有问题的。

  5. Scala使用特征支持有限形式的多重继承。 与接口(其中多个可以用Java实现)不同,特征可以定义方法和变量。

  6. 数组像任何其他类一样透明地处理。

  7. 您可以通过隐式定义向现有类添加方法 例如,您可以向Arrays of Integers添加“sum”方法。

     class IntArray(value: Array[Int]) { def sumIt = value.reduceRight(_+_) } implicit def pimpArray(xs: Array[Int]) = new IntArray(xs) Array(1,2,3).sumIt 

对于上述某些主题,这是另一个很好的资源: http//www.codecommit.com/blog/scala/scala-for-java-refugees-part-5

除了schmmd的优秀答案,Scala的类型系统还有更重要的功能:

  • object是Java中static成员变量和方法的干净替代,例如, object具有自己的类型,可以作为参数传递
  • type声明:您可以为复杂类型定义别名,例如type FactorMap[A] = Map[A, Set[Int]]
  • 抽象类型成员作为泛型样式的替代
  • 自我类型
  • 结构类型
  • currying的多个参数列表
  • 隐式参数和转换,以及视图边界。 这导致了“pimp my library”模式,可以用来模拟Haskell风格的类型类
  • 高阶类型

最后一点是我的最爱之一。 例如,你不能用Java编写简单的通用仿函数接口。 需要 ......

public interface Function<A,B> {
   public B apply(A a);
}

//not valid Java
public interface Functor<C> {
   public <A,B> C<B> map(Function<A,B> fn, C<A> ca);
}

如果你替换像List而不是C这样的具体类型,它就可以工作。 在Java中,您可以抽象出一个包含的内容(例如,通过编写`List),但是您不能在容器本身上进行抽象。 相信我,我试图找到漏洞(结果就是这个 )。 在Scala中,这是一件轻而易举的事:

trait Functor[C[_]] {
   def map[A,B](fn: A => B, ca: C[A]):C[B]
}

object ListFunctor extends Functor[List] {
   def map[A,B](fn: A => B, ca: List[A]):List[B] = ca.map(fn)
}

任何类型系统,你可以编码HList,TList和HOF的类型是相当强大的恕我直言。 有关详细信息,请参阅http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/

我不知道你是否了解Java,但想象Scala的类型系统是这样的:

  • 删除Java对类型和泛型所能做的人为限制
  • 添加函数式语言的常用功能
  • 创新oop /继承前沿

我会更喜欢o wrie,我的键盘jus坏了,对不起!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM