简体   繁体   中英

How to create a Map constructor using Map([K,V]) instead of Map[K,V]?

Using the tuple form seems handing when working with eg, Iterable interfaces. However, the Map type constructor takes two type arguments, and Iterable only takes one (a 2-tuple).

In short, I'd like to do something like: type Map[(+A, +B)] = Map[A, B] , but this is invalid Scala code. Then I could say:

type MapItem = (K,V)
type MyMap = Map[MapItem]

The example use case I have currently is that I have function defined as follows:

def requestDecodeIterable[B, I[X] <: Iterable[X]](reqRx:  Rx[HttpRequest])
(implicit stuff ...): Rx[I[B]] = ...

I'd like to be able to call it like this:

type CodebookNameItem = (CodebookId, CodebookName)
type CodebookNameCollection[+A, +B] = Map[A, B]
requestDecodeIterable[CodebookNameItem, CodebookNameCollection](request)

However, this does not work of course, because CodebookNameCollection takes two type parameters, but I only takes one type parameter.

I think the primary challenge is that you must have a way of ensuring that the single parameter is a Tuple2, and then get the individual types out of it.

I'm not sure if this is possible with just type statements, but you could do something like this:

trait CanBuildIterable[A, B] {
  type Out <: Iterable[B]
}

implicit def defaultCanBuildIterable[A[X] <: Iterable[X], B] = new CanBuildIterable[A[_], B] {
  type Out = A[B]
}

implicit def mapCanBuildIterable[K, V] = new CanBuildIterable[Map[_, _], (K, V)] {
  type Out = Map[K, V]
}

def requestDecodeIterable[B, I](reqRx: Rx[HttpRequest])
(implicit cbi: CanBuildIterable[I, B], ... other implicits ...): Rx[cbi.Out] = ...

You could then call it like requestDecodeIterable[CodebookNameItem, Map[_, _]] , and the return type is a Map[CodebookId, CodebookName] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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