gpt4 book ai didi

scala - `class A[_]` 有什么用?

转载 作者:行者123 更新时间:2023-12-04 10:54:32 27 4
gpt4 key购买 nike

符号类型 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 = _ }
^

有人能告诉我这种类型在 Scala 中是否有用例吗?确切地说,我不是指类型参数中的存在类型或更高种类的类型,仅指那些小 [_]这构成了完整的类型参数列表。

最佳答案

因为我没有得到我期望的答案,我把这个带到scala-language .

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

I'm going to give it a stab here. I think the use of the feature gets clear when talking about type members.

Assume that you have to implement the following trait:

trait Function {
type Out[In]
def apply[In](x: In): Out[In]
}

This would be a (generic) function where the return type depends on the input type. One example for an instance:

val someify = new Function {
type Out[In] = Option[In] def
apply[In](x: In) = Some(x)
}

someify(3) res0: Some[Int] = Some(3)

So far, so good. Now, how would you define a constant function?

val const0 = new Function {
type Out[In] = Int
def apply[In](x: In) = 0
}

const0(3) res1: const0.Out[Int] = 0

(The type const0.Out[Int] is equivalent to Int, but it isn't printed that way.)

Note how the type parameter In isn't actually used. So, here's how you could write it with _:

val const0 = new Function {
type Out[_] = Int
def apply[In](x: In) = 0
}

Think of _ in that case as a name for the type parameter which cannot actually be referred to. It's a for a function on the type level which doesn't care about the parameter, just like on value level:

(_: Int) => 3 res4: Int => Int = <function1>

Except …

type Foo[_, _] = Int
<console>:7: error: _ is already defined as type _
type Foo[_, _] = Int

Compare that with:

(_: Int, _: String) => 3 res6: (Int, String) => Int = <function2>

So, in conclusion:

type F[_] = ConstType // when you have to implement a type member def
foo[_](...) // when you have to implement a generic method but don't
// actually refer to the type parameter (occurs very rarely)

The main thing you mentioned, class A[_], is completely symmetric to that, except that there's no real use case.

Consider this:

trait FlyingDog[F[_]] { def swoosh[A, B](f: A => B, a: F[A]): F[B] }

Now assume you want to make an instance of FlyingDog for your plain old class A.

new FlyingDog[A] { ... }
// error: A takes no type parameters, expected: one
// (aka 'kind mismatch')

There are two solutions:

  1. Declare class A[_] instead. (Don't do that.)

  2. Use a type lambda:

    new FlyingDog[({ type λ[α] = A })#λ]

or even

new FlyingDog[({ type λ[_] = A })#λ]

关于scala - `class A[_]` 有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12778963/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com