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

Newtype incompatibility with ZIO 2.0.0-M6 #821

Open
LukasDBaker opened this issue Dec 3, 2021 · 7 comments
Open

Newtype incompatibility with ZIO 2.0.0-M6 #821

LukasDBaker opened this issue Dec 3, 2021 · 7 comments
Assignees

Comments

@LukasDBaker
Copy link

The ZIO 2.0 update changes the allowed types for all ZIO effects and ZLayers. These changes are incompatible with zio-prelude's Newtype.

As of the 2.0 update, in types of the form ZIO[R, E, A] and ZLayer[R, E, A] neither R nor A is allowed to be an intersection type in almost all of ZIO's functionality (for example conversion of function to layer, ZIO.apply methods, etc.).

Since prelude's Newtype[A].Type is an intersection type (type Type = Base with Tag), ZIO 2.0 cannot easily be used to interface with prelude's Newtype.

Is there a plan to fix this in the future?

Environment:

  • Scala version: 2.12
  • ZIO version: 2.0.0-M6
  • zio-prelude version: 1.0.0-RC8
@kitlangton
Copy link
Member

Gooood point. Will explore this. Thanks for the report!

@juliano
Copy link

juliano commented Mar 21, 2022

Hello there, I've migrated a project recently and started dealing with a related problem, when using zio newtypes in my tests (initially from here):

object UserToken extends Subtype[String] { ... }

// then, for tests I have the following layer
object CreateUser {
  val layer: ZLayer[Random with Sized, Throwable, UserToken] =
    (for {
      req <- RequestsGen.anyCreateUserRequest.runHead.some
        .orDieWith(_ => new RuntimeException("Failure creating request"))
      resp <- ApiClient.send(req)
    } yield resp.userToken).provideSome[Random with Sized](env).toLayer
}

wherever ZIO.service[UserToken] is used now I get:

A Tag may not contain an intersection type, yet have provided: example.model.UserToken.Base with example.model.UserToken.Tag

Maybe it can be useful :)

@alphaho
Copy link
Collaborator

alphaho commented Jul 22, 2022

A workaround I come up with is like below. But not sure whether it breaks the ZEnvironment's mechanism or not in this way.
If it's a viable option, maybe we can put it into the NewType's definition, so that all zio-prelude users can benefit from this.

Maybe @kitlangton can help shed some light on this.
I can raise a PR if this is a good enough solution.

import zio.prelude.Subtype
import zio.test.{Spec, TestEnvironment, ZIOSpecDefault, assertTrue}
import zio.{Scope, ULayer, ZIO, ZLayer}

abstract class SubtypeWithTag[T] extends Subtype[T] { self =>
  // steal from zio.Tag's companion object
  implicit def tag(implicit tag0: zio.EnvironmentTag[self.Type]): zio.Tag[self.Type] = zio.Tag[self.Type](tag0)
}

object ZIOTagCompatibilityTest extends ZIOSpecDefault {
  object UserToken extends SubtypeWithTag[String]
  type UserToken = UserToken.Type

  object ClientName extends SubtypeWithTag[String]
  type ClientName = ClientName.Type

  def userTokenLayer(value: String): ULayer[UserToken]   = ZLayer.succeed(UserToken(value))
  def clientNameLayer(value: String): ULayer[ClientName] = ZLayer.succeed(ClientName(value))

  override def spec: Spec[TestEnvironment with Scope, Any] =
    // my best try to verify that it doesn't break ZEnvironment's mechanism by 
    // getting two services out of the environment
    test("should get the subtype as a service") {
      for {
        userToken  <- ZIO.service[UserToken]
        clientName <- ZIO.service[ClientName]
      } yield assertTrue(userToken == UserToken("Foo")) &&
        assertTrue(clientName == ClientName("Bar"))

    }.provide(userTokenLayer("Foo"), clientNameLayer("Bar"))
}

@sideeffffect
Copy link
Member

@kitlangton I've put you as the assignee because you seem to understand this the most of us.

@kitlangton
Copy link
Member

I wonder if this will be fixed by #949. I'll check this out this week.

@ashwinbhaskar
Copy link

Facing the same issue as well. Is there a temporary work around for this?

@soujiro32167
Copy link

Still not working; sadness

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

No branches or pull requests

7 participants