Open adamw opened 2 years ago
The next step may be to verify if it is possible to add support for other return types like ZManaged
or an effect that meets some requirements
Supporting ZManaged
is a different task - adding a parallel implementation (hopefully sharing some code) for zio. Here it's about supporting code parametrised with the effect type, so if the user provides Resource[F]
for some F[_]
, and where we need to return Resource[F]
as well.
See https://github.com/softwaremill/macwire/issues/190 for zio support
ok, makes sense. It would be also good to create a pure autowire implementation. https://github.com/softwaremill/macwire/issues/191
In scala 2, in fact it's a problem like cps.
https://github.com/ThoughtWorksInc/dsl-domains-cats
In scala 3, it's a problem like cats-effect-cps.
https://github.com/typelevel/cats-effect-cps
I wrote a repo use these to implement wire.
https://github.com/scalax/ce-injection-samples
But it's not what I want. I wrote some suggestion in gitter. I hope it can have some helpful.
I think just use target effect type to support F[_] will be some difficulties.
Wrap a case class like fs2 I think is more "type friendly". Just
// case class[F[_], T](model: F[T])
And provide a simple
Monad[IO]
with any target effect type, we can simple find the target class which need to inject it's constructor.And as the suggestion in gitter, displays the parameter need in building the constructor injection will broken something about "injection by type".
So I think separate effect type and model type can provide a frindly ”type environment“ to solve this problem.
Just have a test and will bring back some freeback.
Sorry for read the code with some misconceptions since I have implemented it in a way with the less correlation.
@adamw I think injection without F[_]
can simply create a model like
// sealed trait Injection
// case class FunctionInjection(val func: Any => Injection, val input: Injection]) extends Injection
// case class ModelInjection(val value: Any) extends Injection
And we can tag this to F[_]
. like
// sealed trait Injection
// case class FunctionInjection(val func: Any => Injection, val input: Injection) extends Injection
// case class EffectInjection(val effectValue: F[Injection]) extends Injection
// case class ModelInjection(val value: Any) extends Injection
I plan to use implicit
to implement a injection since implicit
in scala 2 means context
so in scala 3 it calls context abstraction
. So the code that in my thinking is something like the injection without cats-effect
in macwire.
In the abstraction of Injection
with F[_]
, we can no use to do something like close
, release
because Resource
and many many things will do this for us. It seems that many things in Spring's Injection now just leave it to F[_]
Yes, like ZManaged[A & B, Nothing, C]
, we just print it as
// val a: Injection = implement ZManaged[X, X, A]
// val b: Injection = implement ZManaged[X, X, B]
// val c: Injection = FunctionInjection(func = need => genInjectionC, input = List(a, b))
and we just tag the info in the case class what your ast need. And than we can simply singed it ZManaged[A & B, Nothing, C]
just we won't implement this injection dependent on the type in fact.
tough the email since changing the code above.
Hm, interesting idea - so autowire
would generate a description, of how the injection should be done. And then at run-time, we can pick the appropriate effect.
> Hm, interesting idea - so autowire
would generate a description, of how the injection should be done. And then at run-time, we can pick the appropriate effect.
Just a copy of free.
> Hm, interesting idea - so autowire
would generate a description, of how the injection should be done. And then at run-time, we can pick the appropriate effect.
We just add some tags in ast. like
// case class EffectInjection(val effectValue: F[Injection], val tag: InjectionTag) extends Injection
And all effect do the same thing in the ast. Just provide a execute context is ok. And all the effects use different way to target to the trait Injection
.
In EffectInjection
, the effect value we can point A
in F[A]
to an abstraction.
// trait EffectValue[A]
// case class RigthEffectValue[F[_], A](val effectValue: F[A]) extends EffectValue[A]
// case class EitherEffectValue[F[_, _], E, A](vall effectValue: F[E, A]) extends EffectValue[A]
// and so on
certainly, we can add tags to the model.
Provide a execute context and it can works well like the trait Injection
above. We no need to mind the type it signed, just set all the type to Any
in execute context. Then we can
// case class EffectInjection(val effectValue: EffectValue[Injection], val tag: InjectionTag) extends Injection
Yes, distage
just can do each effect
target to each ast and use each match case
to execute the ast. It can't make all the ast to do the same thing😉.
Change the code above.
From
// case class FunctionInjection(val func: List[Injection] => Injection, val input: List[Injection]) extends Injection
to
// case class FunctionInjection(val func: List[Any] => Injection, val input: List[Injection]) extends Injection
though it's enough
Change the code above
From
// case class FunctionInjection(val func: List[Any] => Injection, val input: List[Injection]) extends Injection
to
// case class FunctionInjection(val func: Any => Injection, val input: Injection) extends Injection
though List[Any]
can replace with Currey, Then it's only a free.
@adamw Wrong, I think all is wrong.
In fact, injection have two parts. 1 is resources, and our app is just dept on part 1
and to be part 2
. Part 1
is just 5 - 6 resources, use zio is ok, use cats is ok, use Future
or use spirng on java
is ok. And get a part 2
from part 1
to run a app is just a shapeless
without F[_]
, or it's macwire's first release
.
So if we use two step injection
, part 1
can esaily solve by coder himself and part 2
is just macwire's first release
.
I use the macwire
(just use wire[Instance]
) to implement cats-effect
's cats.Resource
in this demo1, demo2 with the two step injection
described above.
It seems that just the simple macwire
is already works well with any effect type
, and this demo use some simple way to implement by name injection
.
@mbore It seems that this can answer the question in Gitter😊
Currently autowire works only for
IO
. It would be great if it would:(a) work for any
F[_]
(b) verify (if at all possible?) that all passed effects/factories/resources use the same effect type - or rather, that they can be parametrised with the same effect type