Skip to content

Instantly share code, notes, and snippets.

@louthy
Last active March 9, 2020 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louthy/54e216373d71b7fb4ceb5c619ea3259f to your computer and use it in GitHub Desktop.
Save louthy/54e216373d71b7fb4ceb5c619ea3259f to your computer and use it in GitHub Desktop.
using System;
using LanguageExt;
using LanguageExt.TypeClasses;
using System.Diagnostics.Contracts;
namespace Defunctionalisation
{
class Program
{
static void Main(string[] args)
{
var expr = TwoArg.New(Add.New(), Constant.New(1), Constant.New(1));
var res = ExprModule.Interpret(expr);
}
}
[Union]
public interface OneArgFunction
{
OneArgFunction Negate();
OneArgFunction Custom1(Func<int, int> x);
}
[Union]
public interface TwoArgFunction
{
TwoArgFunction Add();
TwoArgFunction Subtract();
TwoArgFunction Custom2(Func<int, int, int> x);
}
[Union]
public interface Expr
{
Expr Constant(int x);
Expr OneArg(OneArgFunction f, Expr x);
Expr TwoArg(TwoArgFunction f, Expr x, Expr y);
}
public static class OneArgFunctionModule
{
public static Func<int, int> Interpret(OneArgFunction f) => f switch
{
Negate _ => x => -x,
Custom1 (var fn) => fn
};
}
public static class TwoArgFunctionModule
{
public static Func<int, int, int> Interpret(TwoArgFunction f) => f switch
{
Add _ => (x, y) => x + y,
Subtract _ => (x, y) => x - y,
Custom2 (var fn) => fn
};
}
public static class ExprModule
{
public static int Interpret(Expr e) => e switch
{
Constant (var x) => x,
OneArg (var f, var x) => OneArgFunctionModule.Interpret(f)(Interpret(x)),
TwoArg (var f, var x, var y) => TwoArgFunctionModule.Interpret(f)(Interpret(x), Interpret(y)),
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment