什么是'A类[_]`有用吗?

kir*_*uku 7 scala higher-kinded-types

符号类型class A[_]def a[_](x: Any)具有无法在正文中引用的类型参数,因此我没有看到它在哪里有用以及它为什么编译.如果尝试引用此类型参数,则会引发错误:

scala> class A[_] { type X = _ }
<console>:1: error: unbound wildcard type
       class A[_] { type X = _ }
                             ^

scala> def a[_](x: Any) { type X = _ }
<console>:1: error: unbound wildcard type
       def a[_](x: Any) { type X = _ }
                                   ^
Run Code Online (Sandbox Code Playgroud)

有人能告诉我这种类型在Scala中是否有用例?确切地说,我不是指类型参数中的存在类型或更高级的类型,只是那些[_]形成完整类型参数列表的litte .

kir*_*uku 4

因为我没有得到我期望的答案,所以我把它带到了scala-language

\n\n

我在这里粘贴了 Lars Hupel 的答案(因此,所有学分都适用于他),这主要解释了我想知道的内容:

\n\n
\n

我要在这里尝试一下。我认为在谈论类型成员时,该功能的使用变得很清楚。

\n\n

假设您必须实现以下特征:

\n\n
trait Function {\n  type Out[In]\n  def apply[In](x: In): Out[In]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将是一个(通用)函数,其中返回类型取决于输入类型。举个例子:

\n\n
val someify = new Function {\n  type Out[In] = Option[In]   def\n  apply[In](x: In) = Some(x)\n}\n\nsomeify(3) res0: Some[Int] = Some(3)\n
Run Code Online (Sandbox Code Playgroud)\n\n

到目前为止,一切都很好。现在,您将如何定义常量函数?

\n\n
val const0 = new Function {\n  type Out[In] = Int\n  def apply[In](x: In) = 0\n}\n\nconst0(3) res1: const0.Out[Int] = 0\n
Run Code Online (Sandbox Code Playgroud)\n\n

(该类型const0.Out[Int]相当于Int,但不是以这种方式打印的。)

\n\n

请注意类型参数In实际上并未被使用。因此,您可以使用以下方法编写它_

\n\n
val const0 = new Function {\n  type Out[_] = Int\n  def apply[In](x: In) = 0\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这种情况下,可以将_其视为实际上无法引用的类型参数的名称。这是一个类型级别的函数,它不关心参数,就像值级别一样:

\n\n
(_: Int) => 3 res4: Int => Int = <function1>\n
Run Code Online (Sandbox Code Playgroud)\n\n

除了\xe2\x80\xa6

\n\n
type Foo[_, _] = Int\n<console>:7: error: _ is already defined as type _\n       type Foo[_, _] = Int\n
Run Code Online (Sandbox Code Playgroud)\n\n

与以下内容进行比较:

\n\n
(_: Int, _: String) => 3 res6: (Int, String) => Int = <function2>\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以,总而言之:

\n\n
type F[_] = ConstType // when you have to implement a type member def\nfoo[_](...) // when you have to implement a generic method but don\'t\n            // actually refer to the type parameter (occurs very rarely)\n
Run Code Online (Sandbox Code Playgroud)\n\n

您提到的主要内容class A[_]与此完全对称,只是没有真正的用例。

\n\n

考虑一下:

\n\n
trait FlyingDog[F[_]] { def swoosh[A, B](f: A => B, a: F[A]): F[B] }\n
Run Code Online (Sandbox Code Playgroud)\n\n

FlyingDog现在假设您想为您的普通旧 .n实例创建一个实例class A

\n\n
new FlyingDog[A] { ... }\n// error: A takes no type parameters, expected: one\n// (aka \'kind mismatch\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

有两种解决方案:

\n\n
    \n
  1. 改为声明class A[_]。(不要这样做。)

  2. \n
  3. 使用 lambda 类型:

    \n\n
    new FlyingDog[({ type \xce\xbb[\xce\xb1] = A })#\xce\xbb]\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
\n\n

甚至

\n\n
new FlyingDog[({ type \xce\xbb[_] = A })#\xce\xbb]\n
Run Code Online (Sandbox Code Playgroud)\n
\n