SlideShare a Scribd company logo
1 of 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
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 class citzens
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
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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;
}
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;
}
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;
}
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;
}
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
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);
}
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();
}
}
}
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();
});
}
}
public class Program
{
public static void Main()
{
using (var reader = new StreamReader("file.txt"))
{
WriteLine(reader.ReadToEnd());
}
}
}
public class Program
{
public static void Main()
{
string content;
using (var reader = new StreamReader("file.txt"))
{
content = reader.ReadToEnd();
}
//..
}
}
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);
}
}
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.ReadToEnd()
);
}
}
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
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);
}
}
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));
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 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 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 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..."
);
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;
}
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..."
);
}
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")
}
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}");
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);
var host = AppSettings["RavenDB.Host"] ?? "localhost";
int port;
if (!int.TryParse(AppSettings["RavenDB.Port"], out port))
port = 8080;
// ..
public static class Parsing
{
public static Option<int> ParseInt(this string s)
{
int result;
return int.TryParse(s, out result)
? Some(result)
: None;
}
}
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);
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) ? @this : None;
var host = AppSettings["RavenDB.Host"] ?? "localhost";
var port = AppSettings["RavenDB.Port"].ParseInt()
.Where(p => p > 0)
.GetOrElse(8080);
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);
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);
}
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!");
}
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!");
}
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;
};
}
}
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!");
}
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;
};
}
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!");
}
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
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);
}
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;
}
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));
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
elemarjr@gmail.com
elemarjr.com

More Related Content

What's hot

Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2
Technopark
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum Ukraine
 

What's hot (20)

Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2
 
Java VS Python
Java VS PythonJava VS Python
Java VS Python
 
Why Learn Python?
Why Learn Python?Why Learn Python?
Why Learn Python?
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean Code
 
Awt
AwtAwt
Awt
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
PDBC
PDBCPDBC
PDBC
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
 
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, allCiklum net sat12112011-alexander fomin-expressions and all, all, all
Ciklum net sat12112011-alexander fomin-expressions and all, all, all
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Developer Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duoDeveloper Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duo
 
Martin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick ReferenceMartin Fowler's Refactoring Techniques Quick Reference
Martin Fowler's Refactoring Techniques Quick Reference
 
Java_practical_handbook
Java_practical_handbookJava_practical_handbook
Java_practical_handbook
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
 

Viewers also liked

Viewers also liked (20)

DDD na prática :: Implementação tática – Entidades vs Objeto de Valor
DDD na prática :: Implementação tática – Entidades vs Objeto de ValorDDD na prática :: Implementação tática – Entidades vs Objeto de Valor
DDD na prática :: Implementação tática – Entidades vs Objeto de Valor
 
TDC2016POA | Trilha .NET - .NET Entity Core 1.0
TDC2016POA | Trilha .NET - .NET Entity Core 1.0TDC2016POA | Trilha .NET - .NET Entity Core 1.0
TDC2016POA | Trilha .NET - .NET Entity Core 1.0
 
TDC2016POA \ Trilha Analise Negocios - Agregando valor sem trauma: como trans...
TDC2016POA \ Trilha Analise Negocios - Agregando valor sem trauma: como trans...TDC2016POA \ Trilha Analise Negocios - Agregando valor sem trauma: como trans...
TDC2016POA \ Trilha Analise Negocios - Agregando valor sem trauma: como trans...
 
TDC2016POA | Trilha .NET - O que esperar do C# 7
TDC2016POA | Trilha .NET - O que esperar do C# 7TDC2016POA | Trilha .NET - O que esperar do C# 7
TDC2016POA | Trilha .NET - O que esperar do C# 7
 
Inspeção e Adaptação no Scrum com Indicadores de Resultado e Direção | TDC PO...
Inspeção e Adaptação no Scrum com Indicadores de Resultado e Direção | TDC PO...Inspeção e Adaptação no Scrum com Indicadores de Resultado e Direção | TDC PO...
Inspeção e Adaptação no Scrum com Indicadores de Resultado e Direção | TDC PO...
 
TDC 2016 |Trilha DevOps - Dissecando e entendendo pipelines de entrega de sof...
TDC 2016 |Trilha DevOps - Dissecando e entendendo pipelines de entrega de sof...TDC 2016 |Trilha DevOps - Dissecando e entendendo pipelines de entrega de sof...
TDC 2016 |Trilha DevOps - Dissecando e entendendo pipelines de entrega de sof...
 
Palestra: Big Data Open Source com Hadoop - FLISOL 2014 - Curitiba
Palestra: Big Data Open Source com Hadoop - FLISOL 2014 - CuritibaPalestra: Big Data Open Source com Hadoop - FLISOL 2014 - Curitiba
Palestra: Big Data Open Source com Hadoop - FLISOL 2014 - Curitiba
 
TDC2016POA | Trilha Analise de Negocios - Estranho no ninho: Um brasileiro li...
TDC2016POA | Trilha Analise de Negocios - Estranho no ninho: Um brasileiro li...TDC2016POA | Trilha Analise de Negocios - Estranho no ninho: Um brasileiro li...
TDC2016POA | Trilha Analise de Negocios - Estranho no ninho: Um brasileiro li...
 
TDC2016POA | Trilha Analise de Negocios - Inovando em negócios com foco na eX...
TDC2016POA | Trilha Analise de Negocios - Inovando em negócios com foco na eX...TDC2016POA | Trilha Analise de Negocios - Inovando em negócios com foco na eX...
TDC2016POA | Trilha Analise de Negocios - Inovando em negócios com foco na eX...
 
TDC2016POA | Trilha Analise de Negocios - Business Coach, o Analista de Negó...
TDC2016POA | Trilha Analise de Negocios -  Business Coach, o Analista de Negó...TDC2016POA | Trilha Analise de Negocios -  Business Coach, o Analista de Negó...
TDC2016POA | Trilha Analise de Negocios - Business Coach, o Analista de Negó...
 
TDC2016POA | Trilha Agile - Beyond borders: aplicando ágil em times distribuídos
TDC2016POA | Trilha Agile - Beyond borders: aplicando ágil em times distribuídosTDC2016POA | Trilha Agile - Beyond borders: aplicando ágil em times distribuídos
TDC2016POA | Trilha Agile - Beyond borders: aplicando ágil em times distribuídos
 
TDC2016POA | Trilha Agile - Dual-Track Agile: incluindo o PO e o UX no seu pi...
TDC2016POA | Trilha Agile - Dual-Track Agile: incluindo o PO e o UX no seu pi...TDC2016POA | Trilha Agile - Dual-Track Agile: incluindo o PO e o UX no seu pi...
TDC2016POA | Trilha Agile - Dual-Track Agile: incluindo o PO e o UX no seu pi...
 
TDC2016POA | Trilha Analise de Negocios - Como fatiar seu produto em estórias...
TDC2016POA | Trilha Analise de Negocios - Como fatiar seu produto em estórias...TDC2016POA | Trilha Analise de Negocios - Como fatiar seu produto em estórias...
TDC2016POA | Trilha Analise de Negocios - Como fatiar seu produto em estórias...
 
TDC2016POA | Trilha Agile - Agile Marketing: os resultados alcançados com pri...
TDC2016POA | Trilha Agile - Agile Marketing: os resultados alcançados com pri...TDC2016POA | Trilha Agile - Agile Marketing: os resultados alcançados com pri...
TDC2016POA | Trilha Agile - Agile Marketing: os resultados alcançados com pri...
 
TDC2016POA | Trilha Agile - CHA com Scrum Master - Conhecimentos, Habilidades...
TDC2016POA | Trilha Agile - CHA com Scrum Master - Conhecimentos, Habilidades...TDC2016POA | Trilha Agile - CHA com Scrum Master - Conhecimentos, Habilidades...
TDC2016POA | Trilha Agile - CHA com Scrum Master - Conhecimentos, Habilidades...
 
TDC2016POA | Trilha Agile - Agilidade além da TI: Um Relato de Experiencia
TDC2016POA | Trilha Agile - Agilidade além da TI: Um Relato de ExperienciaTDC2016POA | Trilha Agile - Agilidade além da TI: Um Relato de Experiencia
TDC2016POA | Trilha Agile - Agilidade além da TI: Um Relato de Experiencia
 
TDC2016POA | Trilha .NET - Trazendo o poder dos containers ao mundo .NET
TDC2016POA | Trilha .NET -  Trazendo o poder dos containers ao mundo .NETTDC2016POA | Trilha .NET -  Trazendo o poder dos containers ao mundo .NET
TDC2016POA | Trilha .NET - Trazendo o poder dos containers ao mundo .NET
 
TDC2016POA | Trilha Agile - Ágil fora da TI: como expandir o Agil para as are...
TDC2016POA | Trilha Agile - Ágil fora da TI: como expandir o Agil para as are...TDC2016POA | Trilha Agile - Ágil fora da TI: como expandir o Agil para as are...
TDC2016POA | Trilha Agile - Ágil fora da TI: como expandir o Agil para as are...
 
TDC2016 POA | Trilha DevOps - Blue-Green Deployment com Docker
TDC2016 POA | Trilha DevOps - Blue-Green Deployment com DockerTDC2016 POA | Trilha DevOps - Blue-Green Deployment com Docker
TDC2016 POA | Trilha DevOps - Blue-Green Deployment com Docker
 
TDC2016POA | Trilha Analise de Negocios - Especificação por exemplo como fer...
TDC2016POA | Trilha Analise de Negocios -  Especificação por exemplo como fer...TDC2016POA | Trilha Analise de Negocios -  Especificação por exemplo como fer...
TDC2016POA | Trilha Analise de Negocios - Especificação por exemplo como fer...
 

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

C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
Paulo Morgado
 
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docxlab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
DIPESH30
 
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdfCreate a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
shyamsunder1211
 

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

Les nouveautés de C# 6
Les nouveautés de C# 6Les nouveautés de C# 6
Les nouveautés de C# 6
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
New C# features
New C# featuresNew C# features
New C# features
 
Monadic Comprehensions and Functional Composition with Query Expressions
Monadic Comprehensions and Functional Composition with Query ExpressionsMonadic Comprehensions and Functional Composition with Query Expressions
Monadic Comprehensions and Functional Composition with Query Expressions
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
 
C sharp 8
C sharp 8C sharp 8
C sharp 8
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
mobl
moblmobl
mobl
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docxlab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
lab08build.bat@echo offclsset DRIVE_LETTER=1s.docx
 
JDK 8
JDK 8JDK 8
JDK 8
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 
Introduction à Dart
Introduction à DartIntroduction à Dart
Introduction à Dart
 
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
 
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdfCreate a class BinarySearchTree- A class that implements the ADT binar.pdf
Create a class BinarySearchTree- A class that implements the ADT binar.pdf
 
Mixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented language
 

More from tdc-globalcode

More from tdc-globalcode (20)

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devices
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocus
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golang
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
 

Recently uploaded

Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
ciinovamais
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
QucHHunhnh
 
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
ZurliaSoop
 

Recently uploaded (20)

How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POS
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Dyslexia AI Workshop for Slideshare.pptx
Dyslexia AI Workshop for Slideshare.pptxDyslexia AI Workshop for Slideshare.pptx
Dyslexia AI Workshop for Slideshare.pptx
 
Spatium Project Simulation student brief
Spatium Project Simulation student briefSpatium Project Simulation student brief
Spatium Project Simulation student brief
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
Magic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptxMagic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptx
 
ComPTIA Overview | Comptia Security+ Book SY0-701
ComPTIA Overview | Comptia Security+ Book SY0-701ComPTIA Overview | Comptia Security+ Book SY0-701
ComPTIA Overview | Comptia Security+ Book SY0-701
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and Modifications
 
Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
 
PROCESS RECORDING FORMAT.docx
PROCESS      RECORDING        FORMAT.docxPROCESS      RECORDING        FORMAT.docx
PROCESS RECORDING FORMAT.docx
 

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

  • 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. Olá, eu sou Elemar Jr
  • 3. Programação functional com C# Mas, vamos falar de
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. public class Program { public static void Main() { using (var reader = new StreamReader("file.txt")) { WriteLine(reader.ReadToEnd()); } } }
  • 19. public class Program { public static void Main() { string content; using (var reader = new StreamReader("file.txt")) { content = reader.ReadToEnd(); } //.. } }
  • 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. public static TR Using<T, TR>( T input, Func<T, TR> func ) where T : IDisposable { using (input) return func(input); }
  • 22. public class Program { public static void Main() { var content = Using(new StreamReader("file.txt"), reader => reader.ReadToEnd() ); } }
  • 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. 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. 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. public interface IRepository<T, TId> { T GetById(TId id); } O problema com o null
  • 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. 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. 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. 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. 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. 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. 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. 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. var host = AppSettings["RavenDB.Host"] ?? "localhost"; int port; if (!int.TryParse(AppSettings["RavenDB.Port"], out port)) port = 8080; // ..
  • 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. 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. var host = AppSettings["RavenDB.Host"] ?? "localhost"; var port = AppSettings["RavenDB.Port"].ParseInt().GetOrElse(8080);
  • 39. public static Option<T> Where<T>( this Option<T> @this, Func<T, bool> predicate ) => @this.IsSome && predicate(@this.Value) ? @this : None;
  • 40. var host = AppSettings["RavenDB.Host"] ?? "localhost"; var port = AppSettings["RavenDB.Port"].ParseInt() .Where(p => p > 0) .GetOrElse(8080);
  • 41. public interface IRepository<T, TId> { Option<T> GetById(TId id); }
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. WriteLine(Divide(a, b).Match( right: res => $"Result {res}", left: error => $"Error {error}") );
  • 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