Я пытаюсь написать класс значений, который охватывает Scala коллекции Map
и предоставляет альтернативу get
. Я пытаюсь использовать фантомный тип в классе значений и помечать Key
тем же типом, используя метод member
. Если результат member
равен Some(k)
, то пользователь должен иметь возможность вызвать get(k)
и получить V
вместо Option[V]
.
import scala.collection.{Map => M}
class Key[PH, K] private (val k: K) extends AnyVal
object Key {
def apply[PH, K](k: K): Key[PH, K] = new Key(k)
}
class Map[PH, K, V] private (val m: M[K, V]) extends AnyVal {
def member(k: K): Option[Key[PH, K]] = m.get(k).map(_ => Key(k))
def get(key: Key[PH, K]): V = m.get(key.k).get
}
object Map {
def apply[PH, K, V](m: M[K, V]): Map[PH, K, V] = new Map(m)
}
def withMap[K, V, T](m: M[K, V])(cont: (Map[PH, K, V] forSome { type PH }) => T): T = cont(Map(m))
withMap(M("a" -> "a")){ m =>
m.member("a") match {
case Some(v) => println(m.get(v))
case None => println(":(")
}
}
Но в настоящее время он не может скомпилироваться с следующая ошибка:
found : Key[PH(in value $anonfun),String] where type +PH(in value $anonfun)
required: Key[PH(in value cont),String]
case Some(v) => println(m.get(v))
Как мне убедить scalac, что PH
одинаковы?