Skip to content

Idea: ExpressionLens<A, B> #1545

Open
Open

Description

@WorldMaker

An idea that occurred to me in thinking about Lens<A, B> that could be useful in contexts that use EF or similar (maybe even a world where Eff supports Expression compilation) would be a relatively pure subclass ExpressionLens<A, B>. Roughly something like (untested):

using System.Linq.Expression;

public readonly struct ExpressionLens<A, B>(
    public readonly Expression<Func<A, B>> GetExp,
    public readonly Expression<Func<B, Expression<Func<A, A>> SetExp)
    : Lens(GetExp.Compile(), b => SetExp.Compile().Invoke(b).Compile());

The benefit would be reuse of the same underlying Lens in Linq contexts such as in an EF query using a .Select(MyExpressionLens.GetExp) which EF can translate to a database projection in many cases. (Off the top of my head I can't think of a good Linq example for SetExp, but there presumably is one. It also might be too hard to write a nested Expression in that way that compiles reliably, so it may be YAGNI and the idea to only provide GetExp.)

It would probably remain a subclass of Lens rather than the default for the same reason that the C# compiler will only compile a subset of Func<A, B> to Expression<Func<A, B>>. There would remain plenty of uses of Lens where you may not need those restrictions.

Also presumably it would be more complicated work to support a specialization of Prelude.lens(ExpressionLens<A, B>, ExpressionLens<B, C>) that can also return ExpressionLens<A, C>, but especially if that specialization were to exist that would lend additional reason to support an ExpressionLens subclass. .Select(lens(MyExpressionLens, MySubPropertyExpressionLens).GetExp) could be quite useful in some query scenarios.

I don't have any applications I support that use both EF and LanguageExt today so this is mostly an academic exercise for now for me, but thought it an interesting idea to float in case it sparks other ideas.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions