【问题标题】:scala template function vs forSomescala模板函数与forSome
【发布时间】:2013-04-19 22:39:44
【问题描述】:

我正在尝试存在类型。

我正在使用一个函数,该函数需要一个序列,其中该序列的元素都是相同的类型。我有..

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 forSome { type A } 类型的值是A 类型的一对以及一些类型可以依赖于A 的值。如果您想要一个异构列表,您需要该对在Seq 中的每个元素上有所不同,并且您的版本对于整个Seq 有一个A
  • 更进一步,如果您将存在性视为与类型的配对,而将普遍性(您的 bar[X] 泛型)视为具有类型的函数,您的 foobar 类型是同构的, 通过currying/uncurrying。这种关系在像 Agda 这样具有依赖类型的语言中要清晰得多,但如果你足够仔细地眯着眼睛,你也可能在 Scala 中看到它。

标签: scala parameterized-types


【解决方案1】:

不同之处在于,在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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    相关资源
    最近更新 更多