对于上下文,我最近发现了函数式编程,并试图将其合并到现有的Web解决方案中。
到目前为止,我一直在阅读C#中的函数编程,并且一直在尝试创建一个新的控制器,该控制器可以使用语言-ext库执行基本CRUD操作。
我遇到了一些障碍,因为我不确定在访问数据库时是否遵守FP原则。
下面是我到目前为止所使用的代码--请注意,我首先使用的是实体框架代码,由于我无法控制的原因,我被迫使用带有Guid类型的代理键,这就是为什么该方法涉及这么多操作:
// These functions are injected into the controller constructor
// and are curried where appropriate.
Func<int, Either<Error, Widget>> FetchWidgetById; // Impure
Func<Widget, Widget, Either<Error, Widget>> CloneWidget;
Func<Widget, Either<Error, Widget>> SaveToDb; // Impure
Func<Either<Error, Widget>, IHttpActionResult> CreateHttpResponse
public IHttpActionResult Update(Widget updatedWidget)
=> CreateHttpResponse(
GetWidgetById(updatedWidget.HumanReadableId)
.Bind(CloneWidget(updatedWidget))
.Bind(SaveToDb));问题是,我不知道如何发出信号,GetWidgets和UpdateDatabase是不纯的。我遇到了I/O monad的概念,但我认为在language-ext API中不存在这样的东西,而且我没有足够的FP知识来计算出是否有相应的解决方案或名称。
编辑:我找到了一些关于类似但较旧的项目上的monads的文档,这些文档都是由language-ext的同一个作者编写的。值得注意的是,这个项目实际上包括I/O monad,他承认
在C#中,IO单片可能被认为是不必要的,因为所有的东西都有副作用.
发布于 2018-01-30 12:27:42
我不是这方面的专家,但无论如何我都会试一试。我的理解是,如果您想要拥有域逻辑的纯函数,并在此之外处理数据库访问,那么您必须编写大量的样板代码。您必须将域逻辑实现为免费的monads,使用它们编写功能,并最终有一个解释器来运行代码,实际上是触摸数据库。
由于您使用的是语言-ext,请参阅其关于免费monads:https://github.com/louthy/language-ext/wiki/Thinking-Functionally:-Application-Architecture#free-monad的文档。
另见以下例子:
但是,如果您只是想向读者发送代码有副作用的信号,那么在C#中这是不可能的,因为您可以在任何地方执行IO,就像编辑中提到的那样。当然,有系统地遵循惯例是可能的,但我认为你不能超越这一点。这也适用于免费的monads,因为在C#中都没有任何东西可以阻止编写副作用。
https://stackoverflow.com/questions/48486595
复制相似问题