louthy / language-ext

C# functional language extensions - a base class library for functional programming
MIT License
6.52k stars 420 forks source link

is it possible to get generic non terminal cases with the free monad mechanism? #878

Closed gabomgp4 closed 2 weeks ago

gabomgp4 commented 3 years ago

I wish to use the free monad to abstract away some effectful code. I'm trying first with: a case to get an IQueryable of specified type, another case to get map from one type to another type (probably using automapper inside the interpreter for that case). I'm trying to use this code:

[Free]
public interface IO<T>
{
    [Pure] T Pure(T value);
    [Pure] Unit Fail(Error error);
    IQueryable<T> Query();
    TTarget Copy<TSource, TTarget>(TSource source);
}

I tried different combinations, but nothing seems to work. Ideally, I want to get something like this working:

from query in IO.Query<ContactAssociation>()
from ca in query
where ca.ContactId == 1 //this will be a variable not a constant
select ca

For the automapper thing, something like this code would work:

from query in IO.Copy<Contact, Contact2>(originalContact)
select ca

And ca would be a Contact2.

Is it possible? am I thinking with the wrong mindset?

louthy commented 3 years ago

Unfortunately, this is where you hit the limits of C#'s type-system. Because all of the generic arguments need to be available for Select, SelectMany, Map, Bind, etc. So everything breaks down at that point. I have some ideas how to 'hide' the generics, but I'm unlikely to get to that any time soon, and previous attempts have failed, so it's not guaranteed either.

louthy commented 3 years ago

@gabomgp4 I have worked out how this could be done now, so I will update the Free monad code-gen in time. It does require pretty much a rewrite of that code-gen unfortunately, so it won't be done in the short term. I'll keep this open

louthy commented 2 weeks ago

CodeGen is deprecated

But there are now real Free monads (that create a monad from Functor, for free) in version 5.