question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generate unapply for newtype case class

See original GitHub issue

I’m starting to use more and more of this library. In particular, newtypes are quite useful for defining custom typeclass instances:

@newtype case class FirstOf[A](value: A)
object FirstOf {
   implicit def semigroup[A]: Semigroup[A] = Semigroup.instance((a, _) => a)
}

It would be really nice if for these cases unapply would also be generated. This comes in handy in chains involving foldMap, e.g.

list
  .foldMap(person => Map(person.name -> FirstOf(person.age))
  .map { case (name, FirstOf(age)) => ??? } // no need to use `.value` manually

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
carymrobbinscommented, Apr 20, 2018

@oleg-py Experimental idea which improves the performance of unapply -

https://github.com/oleg-py/newtype-unapply/compare/master...carymrobbins:unapply-class

The newtype unapply bytecode posted earlier shows ClassTag being used, which I suspected was slowing things down. So I tried returning Some as you did as well as returning my own Unapply value class. Both performed very close to the case class version.

Here are the benchmarks via sbt clean 'jmh:run TestBenchmark' -

Benchmark                     Mode  Cnt          Score         Error  Unit
testCaseClass                thrpt  200  402211203.871 ±  861246.654  ops/s
testManualSimpleUnapply      thrpt  200  393148121.470 ± 4173139.812  ops/s
testManualUnapplyValueClass  thrpt  200  384478663.022 ±  870967.771  ops/s
testNewTypeSimpleUnapply     thrpt  200  110200664.917 ±  283007.861  ops/s

the testManual benchmarks are for handwritten newtypes, whereas the testNewType one is the macro generated one which contains ClassTag instances.

This may convince me to try to get rid of the ClassTag instances. For one, I dislike that they enable type-based pattern matching on newtypes. And now this. The only use case that I know of for them is to support Array construction, but I think there’s probably a better way to pull that off. For instance, we could have a NewTypeArray type class to support casting to and from newtypes as well as constructing arrays for newtypes. I’m thinking this is probably a better solution that the hacks we’re using with ClassTag to work around the flaky Scala Array machinery.

@joroKr21 Feel free to chime in on this as I know you originally introduced the ClassTag instances.

0reactions
joroKr21commented, Apr 21, 2018

Yes, I introduced ClassTag only to support Arrays. I would be perfectly happy with removing it if we find a replacement for that feature. Maybe even an Array constructor generated by the macro would be enough.

As for unapply I missed the point of pattern matching if the scrutinee is not a supertype. But I guess it’s fine if people find it convenient.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Programming with Functions #4: „unapply” and the newtype ...
The case class automatically implements the apply method, so you can create a new square by writing: val aSquare = Square(1).
Read more >
Scala -- apply unapply rules - case class - Stack Overflow
Given case class C(x: T), for all x, Some(x) == C.unapply(C.apply(x)). The reason I ask is because of the following ...
Read more >
scala-newtype
Note that extractors ( unapply methods) are not generated by newtypes. Using case class gives us a smart constructor (an apply method on...
Read more >
estatico/scala-newtype - Gitter
I'm having issues with Intellij IDEA syntax highlighting the value inside of the @newtype annotated case class... is that to be expected? Does...
Read more >
Scala pattern matching: apply the unapply - Medium
We begin by declaring a very simple case class that we will soon dissect: ... class definition slightly, in order to make FullName.unapply...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found