shapeless
shapeless copied to clipboard
HMap.get does not support subtypes of keys
Regular Map.get
allows using subtypes:
val v = Map(Option("foo") -> "bar", Option(23) -> 13)
val b = v.get(Some("foo")) // "bar"
but the same isn't true of HMap
, because it can't resolve the implicits necessary to prove that the value type is correct:
val v = HMap[(Option ~?> Id)#λ](Option("foo") -> "bar", Option(23) -> 13)
val b = v.get(Some("foo"))
// [error] could not find implicit value for parameter ev: Option ~?> shapeless.Id#λ[Some[String],V]
// [error] val b = v.get(Some("foo"))
// [error] ^
Would it be possible / sensible to make ~?>.λ
variant in K
, or would that cause other problems?
I've had a bit more of a play around, and providing this implicit seems to allow subclassing to work as expected:
implicit def idValueWitnessSubclass[K[_], K1[_] <: K[_], T](implicit rel: K ~?> Id): (K ~?> Id)#λ[K1[T], Id[T]] = new rel.λ
Would it be worth adding this (and idKeyWitnessSubclass
) to object ~?>
?
Not sure if anyone is still watching this, but I've run into a similar issue.
The documentation is pretty ~~dense~~ nonexistent, but I have the following, based on the lone HMap
example:
class FieldMap[Op <: OpBase[Op, Node], Node <: NodeBase[Op, Node], UpdaterT <: AtomicFieldUpdater[Node, FieldT], FieldT]
implicit def updaterToCacheValue[Op <: OpBase[Op, Node], Node <: NodeBase[Op, Node], UpdaterT <: AtomicFieldUpdater[Node, FieldT], FieldT]:FieldMap[Op,Node,UpdaterT,FieldT] = new FieldMap[Op,Node,UpdaterT,FieldT]
type FieldHMap[Op <: OpBase[Op, NodeT], Node <: NodeBase[Op, Node]] = HMap[Lambda[(`UpdaterT <: AtomicFieldUpdater[Node, FieldT]`, FieldT) => FieldMap[Op, Node, UpdaterT, FieldT]]]
(Lambda
comes from https://github.com/non/kind-projector, I assume there's something similar built-in to shapeless, but again, the documentation is rough).
The error message I get is:
[error] /full/path/redacted.scala:39: kinds of the type arguments ([UpdaterT <: edu.brown.lockfree.AtomicFieldUpdater[Node,FieldT], FieldT]edu.brown.lockfree.FieldMap[Op,Node,UpdaterT,FieldT]) do not conform to the expected kinds of the type parameters (type R) in class HMap.
[error] [UpdaterT <: edu.brown.lockfree.AtomicFieldUpdater[Node,FieldT], FieldT]edu.brown.lockfree.FieldMap[Op,Node,UpdaterT,FieldT]'s type parameters do not match type R's expected parameters:
[error] type UpdaterT's bounds <: edu.brown.lockfree.AtomicFieldUpdater[Node,FieldT] are stricter than type _'s declared bounds >: Nothing <: Any
[error] type FieldHMap[Op <: OpBase[Op, Node], Node <: NodeBase[Op, Node]] = HMap[Lambda[(`UpdaterT <: AtomicFieldUpdater[Node, FieldT]`, FieldT) => FieldMap[Op, Node, UpdaterT, FieldT]]]
[error] ^