【问题标题】:Non-unary type constructor bounded by unary type constructor由一元类型构造函数限制的非一元类型构造函数
【发布时间】:2020-09-18 01:07:48
【问题描述】:

标题试图描述以下子类型

implicitly[Map[Int, String] <:< Iterable[(Int, String)]]

类型参数A在这里推断为(Int, String)

def foo[A](cc: Iterable[A]): A = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])

但是尝试使用类型参数边界来实现类似的效果,我能做的最好的事情就是像这样显式指定类型构造函数的数量

def foo[F[x,y] <: Iterable[(x,y)], A, B](cc: F[A, B]): (A, B) = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])

因为以下错误

def foo[F[x] <: Iterable[x], A](cc: F[A]) = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])
// type mismatch;
// [error]  found   : A
// [error]  required: (Int, String)
// [error]   lazy val e: (Int, String) = foo(Map.empty[Int, String])
// [error]                                  ^

因此使用Iterable 作为上限,我们似乎需要一个签名来处理一元类型构造函数SeqSet,以及一个单独的签名来处理二元类型构造函数Map

def foo[F[x] <: Iterable[x], A](cc: F[A]): A                  // When F is Seq or Set
def foo[F[x,y] <: Iterable[(x,y)], A, B](cc: F[A, B]): (A, B) // When F is Map

有没有一种方法可以使用适用于所有三个的类型边界来获得单个签名?换一种说法,我们如何编写一个适用于所有集合的扩展方法?

【问题讨论】:

  • 这种类型推断最好通过广义类型约束而不是类型界限(如您所见)来处理,因为编译器试图很难推断出可以编译的东西,而有了约束,它有更多信息来验证你需要什么。无论如何,为所有集合提供扩展方法通常很难而且没有意义,但您可能想阅读this
  • @LuisMiguelMejíaSuárez 只需发布正确的链接,因为您评论中的链接已损坏docs.scala-lang.org/overviews/core/…。所以看来 typeclass 是解决方案。

标签: scala dictionary scala-collections type-bounds type-constructor


【解决方案1】:

我认为这里的问题是F 设置为Map,善良是错误的。你不得不说:我有一些类型X,它扩展了F[A],所以当我向上转换它时,我可以将它用作F[A] - 这反过来我们想成为Iterable [A的子类型]。如果我们这样问,听起来很难。

这就是为什么我个人会留在:

@ def foo[A](x: Iterable[A]): A = x.head
defined function foo

@ foo(List(1 -> "test"))
res24: (Int, String) = (1, "test")

@ foo(Map(1 -> "test"))
res25: (Int, String) = (1, "test")

“给我任何x,它是Iterable[A] 的实例A”。

如果我必须做一些推导......我可能也会走这条路。我认为这个限制是CanBuildFrom 工作方式的原因 - 为部分类型提供匹配很困难,尤其是在 Map 这样的情况下,所以让我们一次提供整个类型作为参数,以限制推理的数量需要。

【讨论】:

  • 我不确定这是否能回答您的问题,如果需要改进,请告诉我
猜你喜欢
  • 1970-01-01
  • 2020-10-07
  • 2022-12-20
  • 2023-02-02
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
相关资源
最近更新 更多