scala模板函数vs.forSome
我正在试验存在主义类型 我在玩一个函数,该函数需要一个序列,其中seq的元素都是相同类型的。我有scala模板函数vs.forSome,scala,parameterized-types,Scala,Parameterized Types,我正在试验存在主义类型 我在玩一个函数,该函数需要一个序列,其中seq的元素都是相同类型的。我有 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 e
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>
scala>foo(Seq(新AI,新AS))
:12:错误:类型不匹配;
找到:Seq[A[\u>:String with Int]]
必需:Seq[A[X]]用于某些{type X}
foo(序号(新AI、新AS))
^
scala>bar(顺序(新AI、新AS))
:12:错误:方法栏没有类型参数:(as:Seq[A[X]])布尔值e
xist,以便将其应用于参数(Seq[A[\u>:String with Int]]
---因为---
参数表达式的类型与形式参数类型不兼容;
找到:Seq[A[\u>:String with Int]]
必填项:Seq[A[?X]]
条形图(序号(新AI、新AS))
^
:12:错误:类型不匹配;
找到:Seq[A[\u>:String with Int]]
必填项:Seq[A[X]]
条形图(序号(新AI、新AS))
^
斯卡拉>
不同之处在于,在foo
中,您不能引用类型X
,而在bar
中,您可以:
// fails
def foo(as: Seq[A[X]] forSome { type X }) = Set.empty[X]
// btw the same:
def foo(as: Seq[A[_]]) = Set.empty[???] // <-- what would you put here?
// OK
def bar[X](as: Seq[A[X]]) = Set.empty[X]
//失败
def foo(as:Seq[A[X]]forSome{type X})=Set.empty[X]
//顺便说一句:
def foo(as:Seq[A[]]]=Set.empty[???]//对于某些
来说,的范围很重要。您是否尝试过为某些{type X}]
使用Seq[A[X]命令?对于某些来说,考虑存在类型和的一种可能有用的方法是将其视为一对类型和该类型的一个值。所以一些{type a}
的类型sometype的值是一对类型a
以及一些类型可以依赖于a
的值。如果您想要一个异构列表,您需要该对在Seq
中的每个元素上都有所不同,并且您的版本在整个Seq
中都有一个a
。更进一步,如果您认为存在是与类型成对的,而通用(您的bar[X]
generic)是与类型相关的函数,您的foo
和bar
类型通过curry/uncurry是同构的。在像Agda这样的依赖类型的语言中,这种关系要清楚得多,但是如果你足够努力地眯着眼睛,你可能也会在Scala中看到它。