I have a particular type of inefficient iteration which has occurred in at least three methods in an application I’m implementing.
The problem is that in each case, to compute the answer, I logically need to do two different traversals of a data structure. I’d prefer to do the traversal only once, as each traversal applies a function which is considered expensive.
In each case I have a method f
(it is actually a method of the same name as the method itself, but I don’t think that’s important for the algorithm). The method, f
, should be considered expensive to call. Disregarding efficiency, the semantics of each functions that for two of the methods (disjointDown
and subtypep
): first to see if f
always returns Some(true)
. If not, iterate again to see if the call ever returns Some(false)
. And if both checks fail, then delegate to the superclass with super.f(t)
. However, in the third method (inhabited
), the roles of always and ever are reversed, (swapping foreach
and exists
).
Can I do this in one iteration? If I use reduce, I’m forced to finish the iteration, as there’s not clean way to break out of the loop. Also if I use map to compute the sequence of Options, var saveOptions = U.map(_.f(t))
then I’m forced to always iterate entirely through the loop.
case class UnionType(U: Type*) extends Type {
override def inhabited:Option[Boolean] = {
// TODO : Only a single pass ?
if (U.exists(_.inhabited.contains(true)))
Some(true)
else if (U.forall(_.inhabited.contains(false)))
Some(false)
else
super.inhabited
}
// UnionType(U: Type*)
override protected def disjointDown(t: Type): Option[Boolean] = {
// TODO : Only a single pass ?
if (U.forall(_.disjoint(t).contains(true)))
Some(true)
else if (U.exists(_.disjoint(t).contains(false)))
Some(false)
else
super.disjointDown(t)
}
// UnionType(U: Type*)
override def subtypep(t: Type): Option[Boolean] = {
// TODO : Only a single pass ?
if (U.forall(_.subtypep(t).contains(true)))
Some(true)
else if (U.exists(_.subtypep(t).contains(false)))
Some(false)
else
super.subtypep(t)
}
}