scalacheck icon indicating copy to clipboard operation
scalacheck copied to clipboard

Feature request: lazy labels

Open noresttherein opened this issue 2 years ago • 1 comments

Evaluating labels, if they contain formatted input data, can be somewhat expensive. I'd love to see sibling methods, which take a => String argument. I solved it with a very ugly - but working - hack, but it would be great to see it integrated propely.

	private class LazySet[T](lzy : => Set[T]) extends AbstractSet[T] {
		private lazy val evaluated = lzy
		override def contains(elem :T) :Boolean = evaluated.contains(elem)
		override def incl(elem :T) :Set[T] = new LazySet(evaluated + elem)
		override def excl(elem :T) :Set[T] = new LazySet(evaluated - elem)
		override def iterator :Iterator[T] = evaluated.iterator
		override def empty = new LazySet[T](Set.empty[T])
	}

	implicit class PropExtension(private val self :Prop) extends AnyVal {
		def lbl(l : => String) :Prop = self.map { res =>
			res.copy(labels = new LazySet(res.labels + l))
		}
		@inline def lbl_:(l: => String) :Prop = lbl(l)


		def orElse(p : => Prop) = 
			self.combine(Prop.secure(p)) { (first, second) =>
			if (first.failure && second.status.isInstanceOf[Prop.Exception])
				err.println(first.toString + " orElse " + second)
			if (first.success) first
			else second
		}
	}

	implicit class BooleanExtension(private val self :Boolean) extends AnyVal {
		private def prop = Prop(self)

		def lbl(l : => String) :Prop = prop.map { res =>
			res.copy(labels = new LazySet(res.labels + l))
		}
		@inline def lbl_:(l : => String) :Prop = lbl(l)

		def orElse(p : => Prop) = 
			prop.combine(Prop.secure(p)) { (first, second) =>
				if (first.failure && second.status.isInstanceOf[Prop.Exception])
					err.println(first.toString + " orElse " + second)
				if (first.success) first
				else second
			}
	}

noresttherein avatar Jun 06 '23 17:06 noresttherein

@noresttherein I had the same thought! Opened a PR at #979

mrdziuban avatar Jul 07 '23 13:07 mrdziuban