我一直在尝试使用 Free monads 创建 HTTP 客户端,类似于 Rúnar Bjarnason 在演讲中采用的方法,即价格合理的 monads 的可组合应用程序架构。
到目前为止,我可以在这个片段中看到,https://bitbucket.org/snippets/atlassian-marketplace/EEk4X。
它工作正常,但我并不完全满意。最大的痛点是需要对HttpOps
将要嵌入的代数进行参数化,以允许请求和响应主体的流式传输。这使得通过简单地说不可能建立你的代数
type App[A] = Coproduct[InteractOps, HttpcOps[App, ?], A]
如果你尝试,你会illegal cyclic reference
从编译器中得到一个错误。为了解决这个问题,您可以使用案例类
type App0[A] = Coproduct[InteractOps, HttpcOps[App, ?], A]
case class App[A](app0: App0[A])
这解决了循环引用问题,但引入了一个新问题。我们不再有Inject[InteractOps, App]
现成的实例,这意味着我们不再有Interact[App]
andHttpc[HttpcOps[App, ?]]
实例,因此我们必须为我们的代数手动定义它们。对于像这样的小而简单的代数,这并不太繁重,但对于更大的东西,它可以变成很多样板。
是否有另一种方法可以让我们以更方便的方式包含流式传输和组合代数?