簡體   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