Last active
April 3, 2017 08:32
-
-
Save jrgcubano/2a79b10655218c1cdb493f6e4f64a2fa to your computer and use it in GitHub Desktop.
Functional C#examples using lang ext (compose functions, either, etc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ..."); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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