-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add TotalHashMap #8
Comments
Would you consider a more general It's also possible that this should be a separate data structure. |
I was not clear enough, but that's what I meant. By "zero" I meant whatever default value, not related to a zero in any algebraic structure.
For that, you would need an extra bit of information to indicate whether the default value is a Then still, you couldn't have both an infinite number of zeros and an infinite number of ones at the same time. Although this property seems to be preserved under the operations of a Boolean algebra. |
Yes, I had been imagining something like this: package he
class TotalMap[K, V](private[he] val m: Map[K, V], private[he] val d: V) {
def apply(k: K): V =
m.getOrElse(k, d)
def updated(k: K, v: V): TotalMap[K, V] =
new TotalMap(m.updated(k, v), d)
def compress(implicit e: Eq[V]): TotalMap[K, V] =
m.filter { case (_, v) => v =!= d }
def map[W](f: V => W): TotalMap[K, W] =
new TotalMap(m.map { case (k, v) => f(v) }, f(d))
}
object TotalMap {
def constant[K, V](v: V): TotalMap[K, V] =
new TotalMap(Map.empty[K, V], v)
implicit def totalMapRig[K, V: Rig]: Rig[TotalMap[K, V]] =
new TotalMap[K, V] {
def zero: TotalMap[K, V] = constant(Rig[V].zero)
def one: TotalMap[K, V] = constant(Rig[V].one)
def plus(x: TotalMap[K, V], y: TotalMap[K, V]): TotalMap[K, V] = {
val e = constant[K, V](x.d + yd)
(x.m.keys | y.m.keys).foldLeft(e)((m, k) => m.updated(k, x(k) + y(k)))
}
def times(x: TotalMap[K, V], y: TotalMap[K, V]): TotalMap[K, V] = {
val e = constant[K, V](x.d * yd)
(x.m.keys | y.m.keys).foldLeft(e)((m, k) => m.updated(k, x(k) * y(k)))
}
}
implicit def totalMapEq[K, V: Eq]: Eq[TotalMap[K, V]] =
new Eq[TotalMap[K, V]] {
def eqv(x: TotalMap[K, V], y: TotalMap[K, V]): Boolean =
x.d === y.d &&
x.m.forall { case (k, v) => v == y(k) } &&
y.m.forall { case (k, v) => v == x(k) }
}
} In fact once you have this structure you can go on to define a |
(This is just a sketch -- in practice I'd probably want to remove the |
Ah, right, no extra bit needed and no need to restrict the default element On Sep 15, 2016 12:25 PM, "Erik Osheim" [email protected] wrote:
|
A total map is a map that is defined everywhere.
For this data structure, we only consider a special kind of total maps: the ones that are non-zero at at most a finite number of points.
TotalHashMap
can then be implemented using an ordinaryHashMap
for keys with non-zero values, and assume zero everywhere else.EDIT: by "zero" I mean any constant value, not necessarily related to any algebraic notion of zero. So a better phrasing would be that we consider total maps that are constant except for at most a finite number of points.
The text was updated successfully, but these errors were encountered: