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 Type Alias For Intersection Types On Scala 2 #4845

Merged
merged 2 commits into from Mar 27, 2021

Conversation

adamgfraser
Copy link
Contributor

Resolves #4844. Adds a type alias to allow & to be used on both Scala 2 and Scala 3.

@regiskuckaertz
Copy link
Member

regiskuckaertz commented Mar 26, 2021

Bloody hell that was fast 🕺 I refrained from going one step further because of the dotty compat but this would be nicer:

type &[A, B] = Has[A] with Has[B]

What do you think?

I thought about this after @kitlangton 's presentation at zio world. I think it's a great idea to get rid of the type alias boilerplate but Has[_] is 5 characters long and life is too short 😄

jdegoes
jdegoes previously approved these changes Mar 26, 2021
@kitlangton
Copy link
Member

Bloody hell that was fast 🕺 I refrained from going one step further because of the dotty compat but this would be nicer:

type &[A, B] = Has[A] with Has[B]

What do you think?

I thought about this after @kitlangton 's presentation at zio world. I think it's a great idea to get rid of the type alias boilerplate but Has[_] is 5 characters long and life is too short 😄

The following works in Dotty, but there's not much we can do in Scala 2.

type ++[A,B] <: Has[_] = (A,B) match {
  case (Has[_], Has[_]) => A & B & Has[_]
  case (_, Has[_]) => Has[A] & B
  case (Has[_], _) => A & Has[B]
  case (_,_) => Has[A] & Has[B] 
}

val layer = ZLayer.fromAuto[Console ++ String ++ Has[Int] ++ Boolean](layer, boolLayer, Console.live) 

@adamgfraser
Copy link
Contributor Author

@regiskuckaertz I think one of our lessons from ZIO 1.0 has been that hiding the Has data type doesn't pay off in the long term. It seems really nice to avoid writing Has everywhere, which is why we created the type aliases for the services. However, it creates user confusion about which date types are Has and which ones are not and leads to errors when users accidentally created nested Has data types so I think it is best to stick to the simple definition of intersection types that is the same across Scala versions.

@adamgfraser
Copy link
Contributor Author

That is really interesting regarding the match types.

@kitlangton
Copy link
Member

kitlangton commented Mar 27, 2021

While I agree it could be nice to have something like that in Scala 2:

type ++[A,B] = Has[A] with Has[B]

The problem is when you use it to join more than two types, the left hand side is now a Has and will become doubly wrapped, so you'd actually need:

type ++[A,B] = A with Has[B]

But then it's a bit weird to use, as you have to explicitly wrap the first type—or add some second operator that also wraps the lhs. Either way, not too great. Probably best for individuals to implement it themselves in their own libraries if they really want that, until we can figure out something more elegant (like that match type approach).

@regiskuckaertz
Copy link
Member

regiskuckaertz commented Mar 27, 2021

type ++[A,B] <: Has[_] = (A,B) match {
  case (Has[_], Has[_]) => A & B & Has[_]
  case (_, Has[_]) => Has[A] & B
  case (Has[_], _) => A & Has[B]
  case (_,_) => Has[A] & Has[B] 
}

@kitlangton hmm, I see, at that point ++ is not a type alias but a type constructor, like *: for inductive tuples. Then the problem disappears.

@adamgfraser good point, I think this is wise.

@adamgfraser adamgfraser merged commit 9a93356 into zio:master Mar 27, 2021
@adamgfraser adamgfraser deleted the intersection branch April 6, 2021 01:22
@adamgfraser adamgfraser mentioned this pull request Nov 16, 2021
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.

with is too long
4 participants