簡體   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