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

Implement NonEmptyList#Collect #1516

Merged
merged 1 commit into from
Mar 22, 2017
Merged

Implement NonEmptyList#Collect #1516

merged 1 commit into from
Mar 22, 2017

Conversation

xavier-fernandez
Copy link
Contributor

  • "collect" method is really useful when wanting to do a transformation in some of the elements from a collection, applying a partial function. This PR implements this method both for NonEmptyVector and NonEmptyList.

@codecov-io
Copy link

codecov-io commented Jan 5, 2017

Codecov Report

Merging #1516 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1516      +/-   ##
==========================================
+ Coverage   92.33%   92.33%   +<.01%     
==========================================
  Files         247      247              
  Lines        3900     3903       +3     
  Branches      137      139       +2     
==========================================
+ Hits         3601     3604       +3     
  Misses        299      299
Impacted Files Coverage Δ
core/src/main/scala/cats/data/NonEmptyList.scala 98.85% <100%> (+0.04%) ⬆️

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 f6ef91e...d0f6f0b. Read the comment docs.

@johnynek
Copy link
Contributor

johnynek commented Jan 5, 2017

I'm weakly -1 on adding methods which are identical to doing .toList.foo or toVector.foo.

Methods that preserve nonemptiness are more interesting to me.

@xavier-fernandez
Copy link
Contributor Author

What about returning: Option[NonEmptyList[B]]?

@kailuowang
Copy link
Contributor

@xavier-fernandez, unless I am missing something, a Option[NonEmptyList[B]] is as powerful as a List[B] but less convenient. So you do want to return a List[B]. And if you going to lose the nonemptiness anyway why not x.toList.collect? To me it makes the lost of nonemptiness more explicit. Thus I favor that than x.collect that returns a List.
The filter method we have there is an existing example of such methods that don't preserve nonemptines. @ceedubs do you happen to remember the incentive of adding that filter method?

@xavier-fernandez xavier-fernandez deleted the NonEmptyCollections_collect branch January 5, 2017 20:50
@xavier-fernandez xavier-fernandez restored the NonEmptyCollections_collect branch January 5, 2017 20:58
@xavier-fernandez
Copy link
Contributor Author

I should close the PR?

@ceedubs
Copy link
Contributor

ceedubs commented Jan 5, 2017

The main arguments that I can think of for having the filter method is that for NonEmptyList it can be implemented every so slightly more efficiently than toList.filter and that it may be slightly more convenient for users. I do recall at least one time that a coworker has asked me how they should filter a scalaz NonEmptyList, as it isn't necessarily obvious that you should go through List. I'm pretty neutral as to whether or not we include the List-like methods that don't offer anything specific to being non-empty.

@xavier-fernandez
Copy link
Contributor Author

NonEmptyList.collect will have a better performance than toList.collect...

On the other hand,NonEmptyVector.collect will not yield any performance improvement.

@johnynek
Copy link
Contributor

johnynek commented Jan 6, 2017 via email

@xavier-fernandez
Copy link
Contributor Author

If NonEmptyList is having a collect method, it would not be better that NonEmptyVector too, for consistency?

@johnynek
Copy link
Contributor

johnynek commented Jan 7, 2017 via email

@xavier-fernandez xavier-fernandez changed the title Implement 'collect' method for NonEmptyVector and NonEmptyList Implement NonEmptyList#Collect Jan 7, 2017
@xavier-fernandez
Copy link
Contributor Author

Modified the PR so the collect method is only implemented on NonEmptyList

@@ -67,6 +67,30 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) {
}

/**
* Builds a new collection by applying a partial function to
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we say "Builds a new List ..." ?

* scala> nel.collect {
* case v if v % 2 == 0 => "even"
* case _ => "odd"
* }
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this should be :

/**
 * ...
 * scala> nel.collect {
 *      |   case v if v % 2 == 0 => "even"
 *      |   case _ => "odd"
 *      | }
 * ...
 */

for the doctest to be generated correctly.

@xavier-fernandez
Copy link
Contributor Author

@peterneyens amend done :)

@johnynek
Copy link
Contributor

johnynek commented Jan 9, 2017

👍

@peterneyens
Copy link
Collaborator

peterneyens commented Mar 18, 2017

You need to use exactly

     | 

after a scala> for the test to be picked up.

Right now the generated doctest is

    property("example at line 203: nel.collect { case v if v < 3 => v }") = org.scalacheck.Prop.secure {
      sbtDoctestTypeEquals(nel.collect { case v if v < 3 => v })((nel.collect { case v if v < 3 => v }): scala.collection.immutable.List[Int])
      val actual = sbtDoctestReplString(nel.collect { case v if v < 3 => v })
      val expected = "List(1, 2)"
      (actual == expected) :| s"'$actual' is not equal to '$expected'"
    }

So the last "odd" and "even" test is not checked. If you change it to

   /**
    * scala> nel.collect {
    *      |   case v if v % 2 == 0 => "even"
    *      |   case _ => "odd"
    *      | }
    */

It will include this one as well :

    property("example at line 205: nel.collect { ...") = org.scalacheck.Prop.secure {
      sbtDoctestTypeEquals(nel.collect {
  case v if v % 2 == 0 => "even"
  case _ => "odd"
})((nel.collect {
  case v if v % 2 == 0 => "even"
  case _ => "odd"
}): scala.collection.immutable.List[Int])
      val actual = sbtDoctestReplString(nel.collect {
  case v if v % 2 == 0 => "even"
  case _ => "odd"
})
      val expected = "List(odd, even, odd, even, odd)"
      (actual == expected) :| s"'$actual' is not equal to '$expected'"
    }

It would be handy if sbt-doctest gave some kind of error message if it is ignoring lines.

@xavier-fernandez
Copy link
Contributor Author

@peterneyens will fix tomorrow morning, thank you :)

@xavier-fernandez
Copy link
Contributor Author

Did an ammend fixing the DocTest generation :)

Copy link
Collaborator

@peterneyens peterneyens left a comment

Choose a reason for hiding this comment

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

Thanks for the doctest changes.

@kailuowang kailuowang merged commit ec623e4 into typelevel:master Mar 22, 2017
@kailuowang
Copy link
Contributor

👍 merging with 2 sign-offs.

@xavier-fernandez xavier-fernandez deleted the NonEmptyCollections_collect branch March 22, 2017 15:18
@kailuowang kailuowang added this to the 1.0.0-MF milestone Aug 1, 2017
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.

6 participants