Validation Semigroup

95 views
Skip to first unread message

George Leontiev

unread,
Jul 31, 2012, 10:53:10 AM7/31/12
to sca...@googlegroups.com
I'd like to discuss how Validation's Semigroup instance should be changed (if it should be, of course).
Currently, FailProjection and Validation itself have the same instance, for which only left element (i.e., Failure) has to be Semigroup. At the same time, there's an append method, that needs both elements to be Semigroups. The thing, I'm proposing in #114 is to leave the existing instance as an instance for the FailProjection (as it only needs left element to be Semigroup) and create a new default instance for Validation, using that append method.

Alternatively, comparing to Either:
Either does not have a default Semigroup instance. But it does have instances for LeftProjection and RightProjection. Since Validation does not have SuccessProjection, it and a corresponding instance for it can be added. In this case default instance should either use the append method, or be removed.

I would like to hear any thoughts on this.
Also, I'm new to contributing to scalaz project, so please excuse possible misuse of terminology or other silly mistakes. Thanks.

Richard Wallace

unread,
Jul 31, 2012, 12:36:14 PM7/31/12
to sca...@googlegroups.com
This behavior is in line with the `Semigroup` of both `Option` and the new `scalaz.Either` on Tony's topic/either branch, so I've gone ahead and merged the pull request.

I admit I did it before seeing Jason's request for discussion and this thread.  If, for some reason, we decide this isn't the correct behavior we can change it back.  But I really think this is the correct behavior and I'm not sure how it went unnoticed before.

Rich

Matthew Pocock

unread,
Jul 31, 2012, 1:23:20 PM7/31/12
to sca...@googlegroups.com
Hi,

Can you just summarise what the new |+| behaviour would be? The 'truth table', if you like, with Failure playing the role of FALSE and Success playing the role of TRUE. I guess I'm asking if it is failure-biassed (like a logical AND), success-biassed (like a logical OR), or something else.

Failure(e1) |+| Failure(e2) => Failure(e1 |+| e2)
Failure(e1) |+| Success(s2) => ???
Success(s1) |+| Failure(e2) => ???
Success(s1) |+| Success(s2) => Success(s1 |+| s2)

The more I use multiple semigroups for the same types, the more I'm seeing boolean (and n-valued) algebras. Perhaps truth-tables over n-valued logic is to semigroups what systems of counting integers is to data-structures. If we take a code-as-proof view of validation then the terms `e1 |+| e2` and `s1 |+| s2` become the witness values that prove that this alegorical truth-value is correct, and choices of these nested semi-groups are choices over how to combine witness values.

Matthew

--
You received this message because you are subscribed to the Google Groups "scalaz" group.
To view this discussion on the web visit https://groups.google.com/d/msg/scalaz/-/d1sRTFjYoxkJ.
To post to this group, send email to sca...@googlegroups.com.
To unsubscribe from this group, send email to scalaz+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/scalaz?hl=en.



--
Dr Matthew Pocock
Integrative Bioinformatics Group, School of Computing Science, Newcastle University
skype: matthew.pocock
tel: (0191) 2566550

Richard Wallace

unread,
Jul 31, 2012, 1:32:07 PM7/31/12
to sca...@googlegroups.com
From the pull request

scala> val success1 = 1.success[String]
success1: scalaz.Validation[String,Int] = Success(1)

scala> val success2 = 2.success[String]
success2: scalaz.Validation[String,Int] = Success(2)

scala> val success3 = 1.success[String].fail
success3: scalaz.FailProjection[String,Int] = scalaz.Validation$$anon$18@59bdcda

scala> val success4 = 2.success[String].fail
success4: scalaz.FailProjection[String,Int] =
scalaz.Validation$$anon$18@655554a8

scala> success1 |+| success2
res0: scalaz.Validation[String,Int] = Success(3) // was: Success(1)

scala> success3 |+| success4
res1: scalaz.FailProjection[String,Int] = scalaz.Validation$$anon$18@5f6bfe9c

scala> .validation
res2: scalaz.Validation[String,Int] = Success(1)

George Leontiev

unread,
Jul 31, 2012, 1:51:07 PM7/31/12
to sca...@googlegroups.com
For Validation:
scala> val s1 = 1.success[Int]
s1: scalaz.Validation[Int,Int] = Success(1)

scala> val s2 = 2.success[Int]
s2: scalaz.Validation[Int,Int] = Success(2)

scala> val e1 = 1.fail[Int]
e1: scalaz.Validation[Int,Int] = Failure(1)

scala> val e2 = 2.fail[Int]
e2: scalaz.Validation[Int,Int] = Failure(2)

scala> s1 |+| s2
res0: scalaz.Validation[Int,Int] = Success(3)

scala> e1 |+| s2
res1: scalaz.Validation[Int,Int] = Success(2)

scala> s1 |+| e2
res2: scalaz.Validation[Int,Int] = Success(1)

scala> e1 |+| e2
res3: scalaz.Validation[Int,Int] = Failure(3)

For FailProjection:
scala> val s1 = 1.success[Int].fail
s1: scalaz.FailProjection[Int,Int] = scalaz.Validation$$anon$18@30b8b0c9

scala> val s2 = 2.success[Int].fail
s2: scalaz.FailProjection[Int,Int] = scalaz.Validation$$anon$18@1334a8fd

scala> val e1 = 1.fail[Int].fail
e1: scalaz.FailProjection[Int,Int] = scalaz.Validation$$anon$18@435ea4f2

scala> val e2 = 2.fail[Int].fail
e2: scalaz.FailProjection[Int,Int] = scalaz.Validation$$anon$18@55037ead

scala> (s1 |+| s2) validation
res4: scalaz.Validation[Int,Int] = Success(1)

scala> (e1 |+| s2) validation
res5: scalaz.Validation[Int,Int] = Success(2)

scala> (s1 |+| e2) validation
res6: scalaz.Validation[Int,Int] = Success(1)

scala> (e1 |+| e2) validation
res7: scalaz.Validation[Int,Int] = Failure(3)

So, really, the difference is in s1 |+| s2.
--
Cordialement

Matthew Pocock

unread,
Jul 31, 2012, 7:03:54 PM7/31/12
to sca...@googlegroups.com
I've had a go at articulating this idea that multi-constructor semigroups have a correspondence with truth tables. Tentatively, it provides a justification for blessing some semi-groups over two-constructor types as being AND-, or OR-shaped, and for generalising ∧ and ∨ operations over these. So, v1 ∧ v2 would be a success if both v1 and v2 where successful, where as v1∨ v2 would be a success if either v1 or v2 was a success. There are obvious implemenations of ∧ and ∨ for all the common two-constructor types, including Option, Validation and Either. The default implementations of |+| then become references to ∧ or ∨, depending on what is natural for the type. I've not stumbled over useful semigroups for two-constructor types that match other binary boolean operators, but no doubt they exist for something.


Matthew

Tony Morris

unread,
Jul 31, 2012, 7:05:16 PM7/31/12
to sca...@googlegroups.com

I have been working on Either EitherT and Validation on the topic/either branch. Might be worth discussing in that context.

Reply all
Reply to author
Forward
0 new messages