Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Union of Has[_] and Any #3997

@thesamet

Description

@thesamet

In zio-grpc, users can define traits that take two type parameters:

trait MyService[R,C] { 
  def method1(req: Request): ZIO[R with C, Status, Response]
}

Where R represents an environment needed by all the service methods, and C represents metadata that the service is expecting (value changes on each request). Both R and C should be be either a subclass of zio.Has[_] or Any.

The library provides a few operations that allow doing all sort of transformations over R and C separately. For example,

trasformContext[R,C,R1](s: MyService[R,C], f: R1=>R): MyService[R1, C] 

To implement those transformations 4 cases need to be considered : R and C are (Any, Any), (Any, Has[]), (Has[], Any), (Has[], Has[]). This leads to some repetition. To avoid the repetition I wrote the following typeclass that let me handle the 4 cases uniformly:

sealed trait Combinable[R, C] {
  def union(r: R, c: C): R with C
}

object Combinable {
  implicit def anyAny: Combinable[Any, Any]                            =
    new Combinable[Any, Any] {
      def union(r: Any, c: Any): Any = r
    }
  implicit def anyHas[C <: Has[_]]: Combinable[Any, C]                 =
    new Combinable[Any, C] {
      def union(r: Any, c: C): C = c
    }
  implicit def hasAny[R <: Has[_]]: Combinable[R, Any]                 =
    new Combinable[R, Any] {
      def union(r: R, c: Any): R = r
    }
  implicit def hasHas[R <: Has[_], C <: Has[_]: Tag]: Combinable[R, C] =
    new Combinable[R, C] {
      def union(r: R, c: C): R with C = r.union[C](c)
    }
}

And using it whenever I need to union over R and C without any constraints on them. It's somewhat similar to the already existing are AreHas that addresses a similar problem.

It would be nice to consider a way to have something in ZIO to address situations like this. That Combinable would do, or possibly a superclass of Has[_] that can replace Any and would act as zero for union.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions