Skip to content

Instantly share code, notes, and snippets.

@jrgcubano
Last active April 3, 2017 08:32
Show Gist options
  • Save jrgcubano/2a79b10655218c1cdb493f6e4f64a2fa to your computer and use it in GitHub Desktop.
Save jrgcubano/2a79b10655218c1cdb493f6e4f64a2fa to your computer and use it in GitHub Desktop.
Functional C#examples using lang ext (compose functions, either, etc)
static readonly Func<Task<int>, Either<Exception, string>> GetMessage = queryAsync =>
string.Empty;
static readonly Func<string, Task<int>> QueryAsync = queryText =>
new SqlCommand(queryText).ExecuteNonQueryAsync();
static void Run()
{
var either = compose(QueryAsync, GetMessage)("update ...");
}
// from this code to the next one by refactoring
public static Either<string, IDbConnection> Open(Func<IDbConnection> connectionFactory)
{
var connection = connectionFactory();
return match(
Try(() =>
{
connection.Open();
return Unit.Default;
}),
Succ: unit => Right<string, IDbConnection>(connection),
Fail: exception => Left<string, IDbConnection>(exception.GetExceptionChainMessages()));
}
public static Either<string, IDbTransaction> BeginTransaction(Either<string, IDbConnection> connection)
{
return match(
connection,
conn => match(
Try(conn.BeginTransaction),
transaction => Right<string, IDbTransaction>(transaction),
exception => Left<string, IDbTransaction>(exception.GetExceptionChainMessages())),
error => true == false
? Right<string, IDbTransaction>(null)
: Left<string, IDbTransaction>(error));
}
// the solution (break parts)
// use some extensions
public static class Exts
{
public static Try<T> ToTry<T>(this Either<string, T> self) => Try(() =>
match(self,
Right: x => x,
Left: e => failwith<T>(e)));
public static Either<string, T> ToEither<T>(this Try<T> self) =>
match(self,
Succ: val => Right<string, T>(val),
Fail: ex => Left<string, T>(ex.GetExceptionChainMessages())
);
}
// and refactor functions
public static Either<string, IDbConnection> Open(Func<IDbConnection> connectionFactory) =>
Try(() => {
var conn = connectionFactory();
conn.Open();
return conn;
})
.ToEither();
public static Either<string, IDbTransaction> BeginTransaction(Either<string, IDbConnection> connection) =>
(from conn in connection.ToTry()
from tran in Try(conn.BeginTransaction)
select tran)
.ToEither();
// other way to refactor and give another solution (create my own prelude extension)
public static class AppPrelude
{
public static Either<string, T> Safe<T>(Func<T> f)
{
try
{
return f();
}
catch(Exception e)
{
return e.GetExceptionChainMessages();
}
}
}
// and this Either extensions
using static YouApp.AppPrelude:
public static Either<string, IDbConnection> Open(Func<IDbConnection> connectionFactory) =>
Safe(() =>
{
var conn = connectionFactory();
conn.Open();
return conn;
});
public static Either<string, IDbTransaction> BeginTransaction(Either<string, IDbConnection> connection) =>
from conn in connection
from tran in Safe(conn.BeginTransaction)
select tran;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment