Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
C# como você nunca viu!
Conceitos avançados de
programação functional em .NET
Elemar Júnior
@elemarjr
elemarjr@ravendb.net...
Olá, eu sou Elemar Jr
Programação functional com C#
Mas, vamos falar de
Func<int, int> square = x => x*x;
var range = Enumerable.Range(1, 10);
var sqs = range.Select(square);
Funções são 1st cla...
Func<int, bool> isEven = x => x%2 == 0;
var original = new[] {4, 7, 9, 3, 2};
var sorted = original.OrderBy(x => x);
var f...
using System;
using System.Threading.Tasks;
using static System.Linq.Enumerable;
using static System.Console;
class Progra...
using System;
using System.Threading.Tasks;
using static System.Linq.Enumerable;
using static System.Console;
class Progra...
using System;
using System.Threading.Tasks;
using static System.Linq.Enumerable;
using static System.Console;
class Progra...
using System;
using System.Threading.Tasks;
using static System.Linq.Enumerable;
using static System.Console;
class Progra...
class Rectangle
{
public double SideA { get; set; }
public double SideB { get; set; }
public Rectangle(double sideA, doubl...
class Rectangle
{
public double SideA { get; set; }
public double SideB { get; set; }
public Rectangle(double sideA, doubl...
struct class Rectangle
{
public double SideA { get; }
public double SideB { get; }
public Rectangle(double sideA, double s...
struct Rectangle
{
public double SideA { get; }
public double SideB { get; }
public Rectangle(double sideA, double sideB)
...
static IEnumerable<T> Where<T>(
this IEnumerable<T> source,
Func<T, bool> predicate
)
{
foreach (var e in source)
{
if (pr...
using System;
using static System.Diagnostics.Debug;
class Program
{
static void Main()
{
Func<int, int, int> divide =
(a,...
using System;
using static System.Console;
class Resource : IDisposable
{
public Resource() { WriteLine("created ..."); }
...
using System;
using static System.Console;
class Resource //: IDisposable
{
private Resource() { WriteLine("created ...");...
public class Program
{
public static void Main()
{
using (var reader = new StreamReader("file.txt"))
{
WriteLine(reader.Re...
public class Program
{
public static void Main()
{
string content;
using (var reader = new StreamReader("file.txt"))
{
con...
using System;
using System.IO;
using static Functional;
using static System.Console;
public class Program
{
public static ...
public static TR Using<T, TR>(
T input,
Func<T, TR> func
) where T : IDisposable
{
using (input) return func(input);
}
public class Program
{
public static void Main()
{
var content = Using(new StreamReader("file.txt"), reader =>
reader.Read...
public static class Functional
{
public static void Using<T>(
T input,
Action<T> action
) where T : IDisposable
{
using (i...
public class Program
{
public static void Main()
{
Using(new StreamReader("file.txt"), reader =>
{
WriteLine(reader.ReadTo...
public static Func<T, Unit> ToFunc<T>(Action<T> action) => o =>
{
action(o);
return Unit();
};
Action<StreamReader> print ...
public interface IRepository<T, TId>
{
T GetById(TId id);
}
O problema com o null
public struct Option<T>
{
internal T Value { get; }
public bool IsSome { get; }
public bool IsNone => !IsSome;
internal Op...
public struct Option<T>
{
internal T Value { get; }
public bool IsSome { get; }
public bool IsNone => !IsSome;
internal Op...
public struct Option<T>
{
internal T Value { get; }
public bool IsSome { get; }
public bool IsNone => !IsSome;
internal Op...
public struct NoneType { }
public static class Functional
{
public static Option<T> Some<T>(T value) => Option.Of(value);
...
public class Program
{
public static void Main()
{
SayHello("Elemar");
SayHello(null);
}
public static void SayHello(strin...
public static class Option
{
public static Option<T> Of<T>(T value)
=> new Option<T>(value, value != null);
public static ...
public static class Option
{
public static Option<T> Of<T>(T value)
=> new Option<T>(value, value != null);
public static ...
public static Option<Unit> ForEach<T>(
this Option<T> @this,
Action<T> action) =>
Map(@this, ToFunc(action));
Option<strin...
var host = AppSettings["RavenDB.Host"] ?? "localhost";
int port;
if (!int.TryParse(AppSettings["RavenDB.Port"], out port))...
public static class Parsing
{
public static Option<int> ParseInt(this string s)
{
int result;
return int.TryParse(s, out r...
public static T GetOrElse<T>(
this Option<T> @this,
Func<T> fallback) =>
@this.Match(
some: value => value,
none: fallback...
var host = AppSettings["RavenDB.Host"] ?? "localhost";
var port = AppSettings["RavenDB.Port"].ParseInt().GetOrElse(8080);
public static Option<T> Where<T>(
this Option<T> @this,
Func<T, bool> predicate
)
=> @this.IsSome && predicate(@this.Value...
var host = AppSettings["RavenDB.Host"] ?? "localhost";
var port = AppSettings["RavenDB.Port"].ParseInt()
.Where(p => p > 0...
public interface IRepository<T, TId>
{
Option<T> GetById(TId id);
}
public void Run()
{
WriteLine("Starting...");
var f30 = Fibonacci(30);
var f35 = Fibonacci(35);
var f40 = Fibonacci(40);
v...
public void Run2()
{
Func<int, int> fibonacci = Fibonacci;
WriteLine("Starting...");
var f30 = fibonacci(30);
var f35 = fi...
public void Run3()
{
Func<int, int> fibonacci = Fibonacci;
WriteLine("Starting...");
var f30 = fibonacci(30);
WriteLine($"...
public static class Combinators
{
public static Func<T, TResult> Print<T, TResult>(Func<T, TResult> func)
{
return (input)...
public void Run4()
{
var fibonacci = Combinators.Print<int, int>(Fibonacci);
WriteLine("Starting...");
var f30 = fibonacci...
public static Func<T, TResult> Time<T, TResult>(Func<T, TResult> func)
{
return (input) =>
{
var before = DateTime.Now;
va...
public void Run5()
{
var fibonacci = Combinators.Time(
Combinators.Print<int, int>(Fibonacci)
);
WriteLine("Starting...");...
public static double Divide(double a, double b)
{
if (Math.Abs(b) < 0.00001)
{
throw new ArgumentException("b could not be...
public struct Either<TL, TR>
{
internal TL Left { get; }
internal TR Right { get; }
public bool IsLeft => !IsRight;
public...
public static Either<string, double> Divide(double a, double b)
{
if (Math.Abs(b) < 0.00001)
{
return "b could not be 0.";...
public TR Match<TR>(Func<L, TR> left, Func<R, TR> right)
=> IsLeft ? left(Left) : right(Right);
public Unit Match<TR>(Acti...
WriteLine(Divide(a, b).Match(
right: res => $"Result {res}",
left: error => $"Error {error}")
);
elemarjr.com
@elemarjr
linkedin.com/in/elemarjr
elemarjr@ravendb.net
elemarjr@gmail.com
Mantenha contato!
C# como você nunca viu!
Conceitos avançados de
programação functional em .NET
Elemar Júnior
@elemarjr
elemarjr@ravendb.net...
Prochain SlideShare
Chargement dans…5
×

TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de programação funcional em .NET

436 vues

Publié le

C# como você nunca viu: conceitos avançados de programação funcional em .NET

Publié dans : Formation
  • Soyez le premier à commenter

TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de programação funcional em .NET

  1. 1. C# como você nunca viu! Conceitos avançados de programação functional em .NET Elemar Júnior @elemarjr elemarjr@ravendb.net elemarjr@gmail.com elemarjr.com
  2. 2. Olá, eu sou Elemar Jr
  3. 3. Programação functional com C# Mas, vamos falar de
  4. 4. Func<int, int> square = x => x*x; var range = Enumerable.Range(1, 10); var sqs = range.Select(square); Funções são 1st class citzens
  5. 5. Func<int, bool> isEven = x => x%2 == 0; var original = new[] {4, 7, 9, 3, 2}; var sorted = original.OrderBy(x => x); var filtered = original.Where(isEven); Direcionamento a imutabilidade
  6. 6. using System; using System.Threading.Tasks; using static System.Linq.Enumerable; using static System.Console; class Program { static void Main() { Title = "Concurrent problems"; var data = Range(-10000, 20001).Reverse().ToList(); // [10000, 9999, .. -9999, -10000] Action t1 = () => WriteLine($"T1 = {data.Sum()}"); Action t2 = () => { data.Sort(); WriteLine($"T2 = {data.Sum()}"); }; Parallel.Invoke(t1, t2); } }
  7. 7. using System; using System.Threading.Tasks; using static System.Linq.Enumerable; using static System.Console; class Program { static void Main() { Title = "Concurrent problems"; var data = Range(-10000, 20001).Reverse().ToList(); // [10000, 9999, .. -9999, -10000] Action t1 = () => WriteLine($"T1 = {data.Sum()}"); Action t2 = () => { data.Sort(); WriteLine($"T2 = {data.Sum()}"); }; Parallel.Invoke(t1, t2); } }
  8. 8. using System; using System.Threading.Tasks; using static System.Linq.Enumerable; using static System.Console; class Program { static void Main() { Title = "Concurrent problems"; var data = Range(-10000, 20001).Reverse().ToList(); // [10000, 9999, .. -9999, -10000] Action t1 = () => WriteLine($"T1 = {data.Sum()}"); Action t2 = () => { data.Sort(); WriteLine($"T2 = {data.Sum()}"); }; Parallel.Invoke(t1, t2); } }
  9. 9. using System; using System.Threading.Tasks; using static System.Linq.Enumerable; using static System.Console; class Program { static void Main() { Title = "Concurrent problems"; var data = Range(-10000, 20001).Reverse().ToList(); // [100, 99, .. -99, -100] Action t1 = () => WriteLine($"T1 = {data.Sum()}"); Action t2 = () => WriteLine($"T2 = {data.OrderBy(x => x).Sum()}"); Parallel.Invoke(t1, t2); } }
  10. 10. class Rectangle { public double SideA { get; set; } public double SideB { get; set; } public Rectangle(double sideA, double sideB) { SideA = sideA; SideB = sideB; } public double Area => SideA*SideB; }
  11. 11. class Rectangle { public double SideA { get; set; } public double SideB { get; set; } public Rectangle(double sideA, double sideB) { SideA = sideA; SideB = sideB; } public double Area => SideA*SideB; }
  12. 12. struct class Rectangle { public double SideA { get; } public double SideB { get; } public Rectangle(double sideA, double sideB) { SideA = sideA; SideB = sideB; } public double Area => SideA*SideB; }
  13. 13. struct Rectangle { public double SideA { get; } public double SideB { get; } public Rectangle(double sideA, double sideB) { SideA = sideA; SideB = sideB; } public Rectangle WithSideA(double newSideA) => new Rectangle(newSideA, SideB); public Rectangle WithSideB(double newSideB) => new Rectangle(SideB, newSideB); public double Area => SideA*SideB; }
  14. 14. static IEnumerable<T> Where<T>( this IEnumerable<T> source, Func<T, bool> predicate ) { foreach (var e in source) { if (predicate(e)) yield return e; } } Você já conhece High-order functions
  15. 15. using System; using static System.Diagnostics.Debug; class Program { static void Main() { Func<int, int, int> divide = (a, b) => a/b; var divideBy = divide.SwapArgs(); Assert(divide(8, 2) == divideBy(2, 8)); } } static class Extensions { public static Func<T2, T1, TResult> SwapArgs<T1, T2, TResult>( this Func<T1, T2, TResult> f ) => (t2, t1) => f(t1, t2); }
  16. 16. using System; using static System.Console; class Resource : IDisposable { public Resource() { WriteLine("created ..."); } public void Foo() => WriteLine("Foo"); public void Fee() => WriteLine("Fee"); public void Dispose() => WriteLine("cleanup..."); } public class Program { public static void Main() { using (var r = new Resource()) { r.Foo(); r.Fee(); } } }
  17. 17. using System; using static System.Console; class Resource //: IDisposable { private Resource() { WriteLine("created ..."); } public void Foo() => WriteLine("Foo"); public void Fee() => WriteLine("Fee"); void Dispose() => WriteLine("cleanup..."); public static void Use(Action<Resource> block) { var r = new Resource(); // pooling? try { block(r); } finally { r.Dispose(); } } } public class Program { public static void Main() { Resource.Use(r => { r.Foo(); r.Fee(); }); } }
  18. 18. public class Program { public static void Main() { using (var reader = new StreamReader("file.txt")) { WriteLine(reader.ReadToEnd()); } } }
  19. 19. public class Program { public static void Main() { string content; using (var reader = new StreamReader("file.txt")) { content = reader.ReadToEnd(); } //.. } }
  20. 20. using System; using System.IO; using static Functional; using static System.Console; public class Program { public static void Main() { Using(new StreamReader("file.txt"), reader => { WriteLine(reader.ReadToEnd()); }); } } public static class Functional { public static void Using<T>( T input, Action<T> action ) where T : IDisposable { using (input) action(input); } }
  21. 21. public static TR Using<T, TR>( T input, Func<T, TR> func ) where T : IDisposable { using (input) return func(input); }
  22. 22. public class Program { public static void Main() { var content = Using(new StreamReader("file.txt"), reader => reader.ReadToEnd() ); } }
  23. 23. public static class Functional { public static void Using<T>( T input, Action<T> action ) where T : IDisposable { using (input) action(input); } public static TR Using<T, TR>( T input, Func<T, TR> func ) where T : IDisposable { using (input) return func(input); } } O problema com o Void
  24. 24. public class Program { public static void Main() { Using(new StreamReader("file.txt"), reader => { WriteLine(reader.ReadToEnd()); return Unit(); }); } } public struct Unit { } public static class Functional { static readonly Unit unit = new Unit(); public static Unit Unit() => unit; public static TR Using<T, TR>( T input, Func<T, TR> func ) where T : IDisposable { using (input) return func(input); } }
  25. 25. public static Func<T, Unit> ToFunc<T>(Action<T> action) => o => { action(o); return Unit(); }; Action<StreamReader> print = (s) => WriteLine(s.ReadToEnd()); Using(new StreamReader("file.txt"), ToFunc(print));
  26. 26. public interface IRepository<T, TId> { T GetById(TId id); } O problema com o null
  27. 27. public struct Option<T> { internal T Value { get; } public bool IsSome { get; } public bool IsNone => !IsSome; internal Option(T value, bool isSome) { IsSome = isSome; Value = value; } public TR Match<TR>(Func<T, TR> some, Func<TR> none) => IsSome ? some(Value) : none(); } public static class Option { public static Option<T> Of<T>(T value) => new Option<T>(value, value != null); }
  28. 28. public struct Option<T> { internal T Value { get; } public bool IsSome { get; } public bool IsNone => !IsSome; internal Option(T value, bool isSome) { IsSome = isSome; Value = value; } public TR Match<TR>(Func<T, TR> some, Func<TR> none) => IsSome ? some(Value) : none(); } public static class Option { public static Option<T> Of<T>(T value) => new Option<T>(value, value != null); } public static void Main() { string _ = null, s = "Elemar"; var o1 = Option.Of(_); // None var o2 = Option.Of(s); // Some("Elemar") }
  29. 29. public struct Option<T> { internal T Value { get; } public bool IsSome { get; } public bool IsNone => !IsSome; internal Option(T value, bool isSome) { IsSome = isSome; Value = value; } public TR Match<TR>(Func<T, TR> some, Func<TR> none) => IsSome ? some(Value) : none(); } public static class Option { public static Option<T> Of<T>(T value) => new Option<T>(value, value != null); } public static void Main() { string _ = null, s = "Elemar"; var o1 = Option.Of(_); // None var o2 = Option.Of(s); // Some("Elemar") } public void SayHello(string name) => WriteLine(GreetingFor(name)); public string GreetingFor(string name) => Option.Of(name).Match( some: n => $"Hello {n}", none: () => "Sorry..." );
  30. 30. public struct NoneType { } public static class Functional { public static Option<T> Some<T>(T value) => Option.Of(value); public static readonly NoneType None = new NoneType(); … public struct Option<T> { ... public static readonly Option<T> None = new Option<T>(); public static implicit operator Option<T>(T value) => Some(value); public static implicit operator Option<T>(NoneType _) => None; }
  31. 31. public class Program { public static void Main() { SayHello("Elemar"); SayHello(null); } public static void SayHello(string name) => WriteLine(GreetingFor(name)); public static string GreetingFor(Option<string> name) => name.Match( some: n => $"Hello {n}", none: () => "Sorry..." ); }
  32. 32. public static class Option { public static Option<T> Of<T>(T value) => new Option<T>(value, value != null); public static Option<TR> Map<T, TR>( this Option<T> @this, Func<T, TR> func) => @this.IsSome ? Some(func(@this.Value)) : None; } public static void Main() { string _ = null, s = "Elemar"; Func<string, string> greetingFor = name => $"Hello {name}"; var o1 = Option.Of(_).Map(greetingFor); // None var o2 = Option.Of(s).Map(greetingFor); // Some("Hello Elemar") }
  33. 33. public static class Option { public static Option<T> Of<T>(T value) => new Option<T>(value, value != null); public static Option<TR> Map<T, TR>( this Option<T> @this, Func<T, TR> func) => @this.IsSome ? Some(func(@this.Value)) : None; } Option<string> _ = null, s = "Elemar"; _.Map(n => $"Hello {n}"); s.Map(n => $"Hello {n}");
  34. 34. public static Option<Unit> ForEach<T>( this Option<T> @this, Action<T> action) => Map(@this, ToFunc(action)); Option<string> _ = null, s = "Elemar"; _.Map(n => $"Hello {n}").ForEach(WriteLine); s.Map(n => $"Hello {n}").ForEach(WriteLine);
  35. 35. var host = AppSettings["RavenDB.Host"] ?? "localhost"; int port; if (!int.TryParse(AppSettings["RavenDB.Port"], out port)) port = 8080; // ..
  36. 36. public static class Parsing { public static Option<int> ParseInt(this string s) { int result; return int.TryParse(s, out result) ? Some(result) : None; } }
  37. 37. public static T GetOrElse<T>( this Option<T> @this, Func<T> fallback) => @this.Match( some: value => value, none: fallback ); public static T GetOrElse<T>( this Option<T> @this, T @else) => GetOrElse(@this, () => @else);
  38. 38. var host = AppSettings["RavenDB.Host"] ?? "localhost"; var port = AppSettings["RavenDB.Port"].ParseInt().GetOrElse(8080);
  39. 39. public static Option<T> Where<T>( this Option<T> @this, Func<T, bool> predicate ) => @this.IsSome && predicate(@this.Value) ? @this : None;
  40. 40. var host = AppSettings["RavenDB.Host"] ?? "localhost"; var port = AppSettings["RavenDB.Port"].ParseInt() .Where(p => p > 0) .GetOrElse(8080);
  41. 41. public interface IRepository<T, TId> { Option<T> GetById(TId id); }
  42. 42. public void Run() { WriteLine("Starting..."); var f30 = Fibonacci(30); var f35 = Fibonacci(35); var f40 = Fibonacci(40); var f45 = Fibonacci(45); WriteLine("Results: {0}, {1}, {2}, {3}", f30, f35, f40, f45); WriteLine("Done!"); } public int Fibonacci(int n) { if (n == 0) return 0; if (n == 1) return 1; return Fibonacci(n - 1) + Fibonacci(n - 2); }
  43. 43. public void Run2() { Func<int, int> fibonacci = Fibonacci; WriteLine("Starting..."); var f30 = fibonacci(30); var f35 = fibonacci(35); var f40 = fibonacci(40); var f45 = fibonacci(45); WriteLine($"Results: {f30}, {f35}, {f40}, {f45}"); WriteLine("Done!"); }
  44. 44. public void Run3() { Func<int, int> fibonacci = Fibonacci; WriteLine("Starting..."); var f30 = fibonacci(30); WriteLine($"Input: 30 Result: {f30}"); var f35 = fibonacci(35); WriteLine($"Input: 35 Result: {f35}"); var f40 = fibonacci(40); WriteLine($"Input: 40 Result: {f40}"); var f45 = fibonacci(45); WriteLine($"Input: 50 Result: {f45}"); WriteLine($"Results: {f30}, {f35}, {f40}, {f45}"); WriteLine("Done!"); }
  45. 45. public static class Combinators { public static Func<T, TResult> Print<T, TResult>(Func<T, TResult> func) { return (input) => { var result = func(input); WriteLine($"Input: {input} Result: {result}"); return result; }; } }
  46. 46. public void Run4() { var fibonacci = Combinators.Print<int, int>(Fibonacci); WriteLine("Starting..."); var f30 = fibonacci(30); var f35 = fibonacci(35); var f40 = fibonacci(40); var f45 = fibonacci(45); WriteLine($"Results: {f30}, {f35}, {f40}, {f45}"); WriteLine("Done!"); }
  47. 47. public static Func<T, TResult> Time<T, TResult>(Func<T, TResult> func) { return (input) => { var before = DateTime.Now; var result = func(input); WriteLine($"Time to this input: {DateTime.Now - before}"); return result; }; }
  48. 48. public void Run5() { var fibonacci = Combinators.Time( Combinators.Print<int, int>(Fibonacci) ); WriteLine("Starting..."); var f30 = fibonacci(30); var f35 = fibonacci(35); var f40 = fibonacci(40); var f45 = fibonacci(45); WriteLine($"Results: {f30}, {f35}, {f40}, {f45}"); WriteLine("Done!"); }
  49. 49. public static double Divide(double a, double b) { if (Math.Abs(b) < 0.00001) { throw new ArgumentException("b could not be 0."); } return a/b; } O problema com o Exceptions
  50. 50. public struct Either<TL, TR> { internal TL Left { get; } internal TR Right { get; } public bool IsLeft => !IsRight; public bool IsRight { get; } internal Either(TL left) { IsRight = false; Left = left; Right = default(TR); } internal Either(TR right) { IsRight = true; Right = right; Left = default(TL); } public static implicit operator Either<TL, TR>(TL left) => new Either<TL, TR>(left); public static implicit operator Either<TL, TR>(TR right) => new Either<TL, TR>(right); }
  51. 51. public static Either<string, double> Divide(double a, double b) { if (Math.Abs(b) < 0.00001) { return "b could not be 0."; } return a/b; }
  52. 52. public TR Match<TR>(Func<L, TR> left, Func<R, TR> right) => IsLeft ? left(Left) : right(Right); public Unit Match<TR>(Action<L> left, Action<R> right) => Match(ToFunc(left), ToFunc(right));
  53. 53. WriteLine(Divide(a, b).Match( right: res => $"Result {res}", left: error => $"Error {error}") );
  54. 54. elemarjr.com @elemarjr linkedin.com/in/elemarjr elemarjr@ravendb.net elemarjr@gmail.com Mantenha contato!
  55. 55. C# como você nunca viu! Conceitos avançados de programação functional em .NET Elemar Júnior @elemarjr elemarjr@ravendb.net elemarjr@gmail.com elemarjr.com

×