Scala定义自定义类型 - 类型不匹配错误

问题描述 投票:0回答:1

我正在做一个基本的练习来理解scala用户定义类型。请看下面的例子。

type MyType[T <: AnyVal] = (List[Seq[T]], String, String)
val g: MyType = (List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar")

这个编译失败,出现类型错误。

type MyType takes type parameters
[error]     val g: MyType = (List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar")

然而,这个编译成功了。

type MyType[T <: AnyVal] = (List[Seq[T]], String, String)
val g: MyType[Int] = (List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar")

有没有一种方法可以让Scala自动确定类型 而不需要指定确切的参数类型?我知道对于函数,我们可以做如下操作。

import scala.reflect.ClassTag

def f1[T](lst: List[T])(implicit ev: ClassTag[T]) = {
  lst.toArray
}

在这种情况下,我不需要调用f1。国际 明确地,我可以只做f1(...)就可以了。

谢谢!我正在做一个基本的练习来理解scala用户定义类型。

scala generics types scala-collections custom-type
1个回答
2
投票

你可以直接写

val g = (List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar")

编译器会推断出类型。你可以检查 g: MyType[Int] 编译。

你也可以做

def TypeOf[F[_ <: AnyVal]] = new PartiallyAppllied[F]
class PartiallyAppllied[F[_ <: AnyVal]] {
  def apply[A <: AnyVal](fa: F[A]) = fa
}

val g = TypeOf[MyType]((List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar"))

g: MyType[Int]

0
投票

请注意 MyType 是一个 类型构造函数 相对于 正体 我们可以用 :kind 命令在Scala REPL

scala> type MyType[T <: AnyVal] = (List[Seq[T]], String, String)
type MyType

scala> :kind -v MyType
MyType's kind is F[T <: AnyVal]
*(AnyVal) -> *
This is a type constructor: a 1st-order-kinded type.

适当的类型描述 价值观 而类型构造函数则没有,所以在一个 价值 定义 val 𝑥: 𝑇 = 𝑒 该类 T 必须是一个合适的类型。因此,以下是一个语法错误

val g: MyType = (List(Seq(1, 2), Seq(3, 4), (Seq(5, 6))), "foo", "bar")

同理

val g: List = List(42)

是一个语法错误。当类型构造函数应用于类型参数时,会产生一个合适的类型,所以下面的工作是这样的。

val g: List[Int] = List(42)

因为 List[Int] 是一个合适的类型

scala> :kind -v List[Int]
List[Int]'s kind is A
*
This is a proper type.
© www.soinside.com 2019 - 2024. All rights reserved.