Skip to content
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 docs for Ior #1822

Merged
merged 6 commits into from
Sep 20, 2017
Merged

Add docs for Ior #1822

merged 6 commits into from
Sep 20, 2017

Conversation

LukaJCB
Copy link
Member

@LukaJCB LukaJCB commented Aug 17, 2017

Some basic usage so far. Might make sense to also document more of the methods available on Ior:)

@LukaJCB LukaJCB mentioned this pull request Aug 17, 2017
70 tasks
@codecov-io
Copy link

codecov-io commented Aug 17, 2017

Codecov Report

Merging #1822 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1822   +/-   ##
=======================================
  Coverage   95.54%   95.54%           
=======================================
  Files         248      248           
  Lines        4420     4420           
  Branches      121      124    +3     
=======================================
  Hits         4223     4223           
  Misses        197      197

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7c74048...01aa2f0. Read the comment docs.

Copy link
Contributor

@kailuowang kailuowang left a comment

Choose a reason for hiding this comment

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

noice, thanks!

@kailuowang kailuowang modified the milestone: 1.0.0-RC1 Aug 29, 2017
Copy link
Contributor

@ceedubs ceedubs left a comment

Choose a reason for hiding this comment

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

Thanks @LukaJCB. Good stuff!

I left one small comment about an Xor reference that I think it might be a good idea for us to change.

My favorite example of Ior is using List[A Ior B] as a return type for a method that zips two lists together, but I suppose it would be out of place to shove that example into this doc :)

# Ior

`Ior` represents an inclusive-or relationship between two data types.
This makes it very similar to the [`Either`](either.html) data type, which represents an `Xor` relationship.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit hesitant about this Xor reference. I think that this might be confusing, as Cats no longer has an Xor type. For consistency with the previous sentence, it might be better to write this as "which represents an exclusive-or" relationship.

In logic/circuits, this is often written as XOR, which we could potentially use, but I think that exclusive-or is more straightforward.


def validateUsername(u: String): Failures Ior Username = {
if (u.isEmpty)
Nel.of("Can't be empty").leftIor
Copy link
Collaborator

Choose a reason for hiding this comment

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

Without the Ior syntax, you could do Ior.leftNel("Can't be empty").

if (p.length < 8)
Nel.of("Password too short").leftIor
else if (p.length < 10)
Ior.both(Nel.of("Password should be longer"), Password(p))
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you are creating a one element NonEmptyList you can use NonEmptyList.one instead of NonEmptyList.of.

import cats.implicits._
import cats.data.{ NonEmptyList => Nel }

type Failures = Nel[String]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if we want to introduce that here, but there also is a IorNel type alias.

@peterneyens
Copy link
Collaborator

Something which would be nice as well is to show the difference between the Applicative behaviour and the Semigroup behaviour, potentially in comparison with Either and Validated.

Something like :

import cats.data.{ IorNel, NonEmptyList, ValidatedNel }
import cats.implicits._

val oddOrEvenEither: Int => Either[Int, Int] = 
  n => Either.cond(n % 2 == 0, n, n)

val oddOrEvenValidatedNel: Int => ValidatedNel[Int, Int] =
  oddOrEven(_).toValidated.toValidatedNel

val oddOrEvenIorNel: Int => IorNel[Int, Int] =
  oddOrEven(_).toIor.leftMap(NonEmptyList.one)

type OddEither[A] = Either[Int, A]
type OddNelVal[A] = ValidatedNel[Int, A]
type OddNelIor[A] = IorNel[Int, A]

val nel = NonEmptyList.of(1, 2, 3, 4, 5)

// Ior short circuits like Either

nel.traverse[OddEither, Int](oddOrEvenEither)       // Left(1)
nel.traverse[OddNelVal, Int](oddOrEvenValidatedNel) // Invalid(NonEmptyList(1, List(3, 5)))
nel.traverse[OddNelIor, Int](oddOrEvenIorNel)       // Left(NonEmptyList(1, List()))

// for Either and Validated, Semigroup same result as with applicative
// but for Ior gives both sides

nel.reduceMap(oddOrEvenEither)        // Left(1)
nel.reduceMap(oddOrEvenValidatedNel)  // Invalid(NonEmptyList(1, List(3, 5)))
nel.reduceMap(oddOrEvenIorNel)        // Both(NonEmptyList(1, List(3, 5)), 6)

I can add this in a follow up PR if needed.

@ceedubs
Copy link
Contributor

ceedubs commented Sep 20, 2017

LGTM. @peterneyens are there any pending items you wanted to see make it into this before merging?

@peterneyens
Copy link
Collaborator

No, I'll follow up with another PR.

@peterneyens peterneyens merged commit de7b7e1 into typelevel:master Sep 20, 2017
@LukaJCB LukaJCB deleted the add-ior-docs branch September 20, 2017 15:57
@kailuowang kailuowang added this to the 1.0.0-RC1 milestone Oct 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants