Functional programming in C #: how to treat IO in CRUD?

In context, I recently discovered functional programming and am trying to incorporate it into an existing Web API solution.

So far I have been reading Functional Programming in C # , and I was trying to create a new controller that could do basic CRUD using the language-ext library.

I run into obstacles because I'm not sure if I support the principles of FP when accessing the database.

Here is the code that I still have - note that I use the Entity Framework Code First, and that for reasons beyond my control I have to use surrogate keys with type Guid , so many operations related to the method:

  // 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)); 

The problem is that I'm not sure how to signal that GetWidgets and UpdateDatabase unclean. I came across the concept of an I / O monad, but I donโ€™t think that such a thing exists in the language-ext API, and I donโ€™t have enough knowledge about FP to work if there is an equivalent solution or name for it.

EDIT: I found some documentation on monads on a similar, but older project by the same author language-ext . It is interesting to note that this project actually includes an I / O monad, in which it recognizes that

Monk IO can be seen as unnecessary in C #, where everything has side effects ...

+5
source share
1 answer

I am not an expert in this, but I will give him a chance anyway. I understand that if you want to have pure functions for domain logic and handle database access outside of this, you will have to write quite a few templates. You will need to implement the domain logic as free monads, compile the functionality using them, and finally have an interpreter to run the code, actually touching the database.

Since you are using language-ext , refer to its documentation on free monads: https://github.com/louthy/language-ext/wiki/Thinking-Functionally:-Application-Architecture#free-monad

See also the following examples:

But if you just want to tell readers that the code has side effects, in C # this is really not possible, because you could do IO anywhere, as mentioned in your edit. Of course, it is possible to be systematic and follow conventions, but I do not think that you can go much further than this. This also applies to free monads, since nothing prevents you from writing side effects there or in C #.

+1
source

Source: https://habr.com/ru/post/1274993/


All Articles