Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@adamgfraser
Copy link
Contributor

Following up on discussions in #1438 this upgrades AssertResult to BoolAlgebra by adding a Not subtype to the algebraic data type. This lets us clean things up a lot because we don't need an Either embedded within it anymore to represent failure. It also allows us to preserve all information as we combine different assertions and implement all logical operations on assertion results including negation and more complex operators like implication, though that is not implemented here. We may want to rethink some of the other backend supporting data structures based on this but I think this is already a big enough PR. No significant changes to the API for users.

ghostdogpr
ghostdogpr previously approved these changes Sep 6, 2019
Copy link
Member

@ghostdogpr ghostdogpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nice! It makes the Assertion code a lot simpler.

@adamgfraser
Copy link
Contributor Author

Thanks! Yeah, I think there is even more we can do but wanted to take it one step at a time.

* a failure.
*/
final def failures: Option[BoolAlgebra[A]] =
fold[Either[BoolAlgebra[A], BoolAlgebra[A]]](a => Right(success(a)))(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to go through Either here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do to deal with the not case. If we don't use Either then notCase turns Some into None, but what does it do with None? We've lost information by only using the option so for example if we had not(not(a)) we could't recover the original value, whereas a.swap.swap == a. Open to more elegant ways for achieving that but I think we definitely need some intermediate structure and Either seems to work relatively well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course 👍

* the specified collection.
*/
final def all[A](as: Iterable[BoolAlgebra[A]]): Option[BoolAlgebra[A]] =
if (as.isEmpty) None else Some(as.reduce(_ && _))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the empty case does not disprove the assumption, so should be true by default.

* the specified collection.
*/
final def any[A](as: Iterable[BoolAlgebra[A]]): Option[BoolAlgebra[A]] =
if (as.isEmpty) None else Some(as.reduce(_ || _))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, there is nothing to prove so the empty case is failure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, same thing as before, you need an A for the failure. ok scratch that then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, exactly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I'm correct, it's not strictly a bool algebra though, as there should be one and only one "false" element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm definitely not an expert on this. I think in boolean algebra as a branch of mathematics there is only one true and one false element. I was more trying to go for the idea that it is a reification, an "algebra", of boolean operations. I'm not committed to the name though not sure about a better one. Any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oooh yeah, that makes sense. I don't have a better proposition either way 😆

@adamgfraser adamgfraser requested a review from jdegoes September 8, 2019 22:46
jdegoes
jdegoes previously approved these changes Sep 9, 2019
Copy link
Member

@jdegoes jdegoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very slick! Not sure about the name, but I think the results (in code volume / clarity) speak for themselves. Excellent work!

@adamgfraser
Copy link
Contributor Author

Yeah, I agree with you about the name. What about Result? The two concrete types we have that instantiate it are:

type AssertResult = BoolAlgebra[AssertionValue]
type TestResult   = BoolAlgebra[FailureDetails]

So maybe this is a general "result" type that can be instantiated with specific types of result data. That is already very consistent with the Scaladoc I have now.

@adamgfraser
Copy link
Contributor Author

@jdegoes Any other thoughts on names for this? Would be nice to get it merged so we can start building on it.

@ghostdogpr
Copy link
Member

@adamgfraser can you solve the conflict?

Also, let's merge it and rename it later if we find a better name?

@adamgfraser
Copy link
Contributor Author

@ghostdogpr I just solved the conflict.

Agree.

@ghostdogpr ghostdogpr merged commit b6e1fa5 into zio:master Sep 12, 2019
@adamgfraser adamgfraser deleted the boolalgebra branch September 12, 2019 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants