For 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've been trying to create a new controller that would be able to do basic CRUD using the language-ext library.
I'm running into a bit of an obstacle as I am not sure if I am keeping to FP principles when accessing the database.
Here is the code I have so far--please note that I am using Entity Framework Code First, and that for reasons beyond my control I am forced to use surrogate keys with type Guid
, which is why there are so many operations involved in 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 am not sure how to signal that GetWidgets
and UpdateDatabase
are impure. I have come across the concept of the I/O monad but I don't think such a thing exists in the language-ext
API, and I don't have enough FP knowledge to work out if there is an equivalent solution or name for it.
EDIT: I've found some documentation on monads on a similar but older project by the same author of language-ext
. It's interesting to note that this project actually includes the I/O monad for which he acknowledges that
The IO monad may be seen as unnecessary in C# where everything has side-effects...
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
I'm not an expert in any of this, but I'll give it a shot in any case. My understanding is that if you want to have pure functions for domain logic and handle database access outside of this, you'll have to write quite a lot of boilerplate code. You'll have to have domain logic implemented as free monads, compose functionality using them, and finally have an interpreter to run the code, actually touching the database.
Since you are using language-ext, please refer to its documentation about free monads: https://github.com/louthy/language-ext/wiki/Thinking-Functionally:-Application-Architecture#free-monad
See also these examples:
But, if you are just looking to signal to readers where code has side effects, it is not really possible in C#, because you could do IO anywhere, as was mentioned in your edit. Of course, being systematic and following conventions is possible, but I don't think you can go much beyond that. This applies to free monads as well, since nothing prevents from writing side effects there either in C#.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With