繁体   English   中英

如何定义类型参数,该参数可以是类型,也可以是该类型的容器?

[英]How to define a type parameter that can be either a type or a container for that type?

我想定义一个这样的类:

class MyClass[C,X](
  val states: C,
  val transform: C => X
)

X只能是等于C或容器C ,像List[C]Set[C] -它不手头意义的问题,如果X是定义为别的。

有没有办法在Scala中强加此限制?

你可以试试

import scala.language.higherKinds

class MyClass[C, F[_]](
                       val states: C,
                       val transform: C => F[C]
                      )

type Id[A] = A

new MyClass[Int, Set](1, Set(_)) // Set[Int] is a container for Int
new MyClass[String, List]("a", List(_)) // List[String] is a container for String
new MyClass[Boolean, Id](true, x => x) // Id[Boolean] is Boolean itself

编辑

假设XY问题。 现在,此帖子有两个答案:

  1. 依赖子类的繁琐解决方案
  2. 基于类型的解决方案,可能会解决实际的X

子分类解决方案

如果你跑

List(List(0), Set(0))

在解释器中,您将看到ListSet仅在Iterable处统一。

因此,您可以做出的最具体的限制是:

import scala.language.higherKinds

class MyClass[C, Container[X] <: collection.immutable.Iterable[X]] (
  val states: C,
  val transform: C => Container[C]
)

我不建议使它如此通用。 如有疑问,请首先使用List ,然后仅在确实有必要时才进行概括。


类型类解决方案

从您的评论看来,这似乎是一个XY问题,而您真正想要的是带有适当类型类的类型构造函数F

首先定义您的类型类,例如,限制一个类能够遍历F

trait MyTC[F[_]] {
  def hasIterator[X](fx: F[X]): Iterator[X]
}

然后为存在类型类实例的任意F定义MyClass

class MyClass[X, F[_] : MyTC] {
  val states: X
  val transform: X => F[X]
}

然后只需为ListSetId定义MyTC实例:

implicit object ListMyTC extends MyTC[List] {
  def hasIterator[X](lx: List[X]): Iterator[X] = lx.iterator
}

type Id[X] = X
implicit object ListMyTC extends MyTC[Id] {
  def hasIterator[X](x: X): Iterator[X] = Iterator(x)
}

然后可以将MyClassListId

val m1 = new MyClass[Int, List] { ... } // Integer states, transforms to List
val m2 = new MyClass[String, Id] { ... } // String-labeled states, transforms to other `String`

等等

这个想法基本上是更换您尝试外延上列举了,你认为你的建筑可能是由描述法工作的所有容器类型,即接受任何F能够证明其满足所有要求MyTC提供的实例MyTC[F]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM