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

Extend cats-autowire to handle any effect type #189

Open
adamw opened this issue Dec 23, 2021 · 20 comments
Open

Extend cats-autowire to handle any effect type #189

adamw opened this issue Dec 23, 2021 · 20 comments
Labels

Comments

@adamw
Copy link
Member

adamw commented Dec 23, 2021

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

@adamw adamw added the autowire label Dec 23, 2021
@mbore
Copy link
Contributor

mbore commented Dec 23, 2021

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

@adamw adamw changed the title Extends cats-autowire to handle any effect type Extend cats-autowire to handle any effect type Dec 23, 2021
@adamw
Copy link
Member Author

adamw commented Dec 23, 2021

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.

@adamw
Copy link
Member Author

adamw commented Dec 23, 2021

See #190 for zio support

@mbore
Copy link
Contributor

mbore commented Dec 23, 2021

ok, makes sense. It would be also good to create a pure autowire implementation. #191

@djx314
Copy link

djx314 commented Aug 16, 2022

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.

@djx314
Copy link

djx314 commented Aug 18, 2022

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.

@djx314
Copy link

djx314 commented Aug 18, 2022

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.

@djx314
Copy link

djx314 commented Nov 17, 2022

@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.

@djx314
Copy link

djx314 commented Nov 17, 2022

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[_]

@djx314
Copy link

djx314 commented Nov 17, 2022

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.

@djx314
Copy link

djx314 commented Nov 18, 2022

tough the email since changing the code above.

@adamw
Copy link
Member Author

adamw commented Nov 18, 2022

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.

@djx314
Copy link

djx314 commented Nov 19, 2022

> 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.

@djx314
Copy link

djx314 commented Nov 19, 2022

> 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.

@djx314
Copy link

djx314 commented Nov 19, 2022

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

@djx314
Copy link

djx314 commented Nov 19, 2022

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😉.

@djx314
Copy link

djx314 commented Nov 24, 2022

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

@djx314
Copy link

djx314 commented Dec 1, 2022

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.

@djx314
Copy link

djx314 commented Dec 11, 2022

@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.

@djx314
Copy link

djx314 commented Jan 8, 2023

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😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants