0
我正在試驗存在類型。scala模板函數vs forSome
我正在玩一個函數,期望一個序列,該序列的元素都是相同的類型。我有..
def bar[X](as: Seq[A[X]]) = true
哪裏...
// parametised type to use in the question
trait A[T]
我再跨越「forSome」語法來了,發現我可以用它實現同樣的約束。
我寫的比較的目的如下...
// useful types
trait A[T]
class AI extends A[Int]
class AS extends A[String]
// define two functions that both have the same constraint.
// ie the arg must be a Sequence with all elements of the same parameterised type
def foo(as: Seq[A[X]] forSome { type X }) = true
def bar[X](as: Seq[A[X]]) = true
// these compile because all the elements are the same type (AI)
foo(Seq(new AI, new AI))
bar(Seq(new AI, new AI))
// both these fail compilation as expected because
// the X param of X[A] is different (AS vs AI)
foo(Seq(new AI, new AS))
bar(Seq(new AI, new AS))
什麼我想明白的是 - 我這麼想嗎? 一個簽名相對於另一個簽名有什麼好處。
一個明顯的差異是編譯錯誤是不同的。
scala> foo(Seq(new AI, new AS))
<console>:12: error: type mismatch;
found : Seq[A[_ >: String with Int]]
required: Seq[A[X]] forSome { type X }
foo(Seq(new AI, new AS))
^
scala> bar(Seq(new AI, new AS))
<console>:12: error: no type parameters for method bar: (as: Seq[A[X]])Boolean e
xist so that it can be applied to arguments (Seq[A[_ >: String with Int]])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Seq[A[_ >: String with Int]]
required: Seq[A[?X]]
bar(Seq(new AI, new AS))
^
<console>:12: error: type mismatch;
found : Seq[A[_ >: String with Int]]
required: Seq[A[X]]
bar(Seq(new AI, new AS))
^
scala>
了'forSome'的範圍是很重要的。你是否嘗試過'Seq [A [X] forSome {type X}]'?考慮存在型和forSome型的一種可能有用的方法是將其視爲一種類型和這種類型的值。因此,sometype for some {type A}類型的值就是一對「A」類型以及一些類型可以取決於「A」的值。如果你想要一個異構列表,你需要這個對在Seq'中的每個元素上有所不同,而你的版本對整個'Seq'都有一個'A'。 – 2013-04-26 19:55:18
更進一步,如果將存在與存在類型和普遍存在(你的'bar [X]'泛型)的對視爲與類型相關的函數,那麼'foo'和'bar'類型是同構的,通過currying/uncurrying。這種關係在像Agda這樣依賴類型的語言中更加清晰,但是如果你足夠眯眼,你可能會在Scala中看到它。 – 2013-04-26 19:58:52