I experimented with creating an HTTP client using Free monads, similar to the approach taken in a conversation by Runnar Bjarnason, Compiled application architecture with reasonable low-cost monads .
What I still have can be seen in this snippet, https://bitbucket.org/snippets/atlassian-marketplace/EEk4X .
Everything is working fine, but I'm not completely satisfied. The biggest point of pain is caused by the need to parameterize HttpOps
over the algebra into which it will be embedded in order to provide a stream representation of the request and response bodies. It makes it impossible to create your algebra simply by saying
type App[A] = Coproduct[InteractOps, HttpcOps[App, ?], A]
If you try, you will get an error illegal cyclic reference
from the compiler. To solve this problem you can use case class
type App0[A] = Coproduct[InteractOps, HttpcOps[App, ?], A]
case class App[A](app0: App0[A])
This solves the problem of cyclic task, but introduces a new problem. We no longer have instances Inject[InteractOps, App]
, which means we no longer have instances Interact[App]
and Httpc[HttpcOps[App, ?]]
therefore we must manually define them for our algebra. For a small and simple algebra such as this, this is not too burdensome, but for something more, it can turn into many patterns.
Is there any other approach that would allow us to enable stream and layout of algebras in a more convenient way?
source
share