Pull to refresh
  • by relevance
  • by date
  • by rating

Functional C#: работа с ошибками

Programming *.NET *C# *ООP *Functional Programming *
В этой части мы рассмотрим как иметь дело со сбоями и ошибками ввода в функциональном стиле.

Читать дальше →
Total votes 24: ↑19 and ↓5 +14
Views 26K
Comments 20

Simplify working with parallel tasks in C# (updated)

.NET *C# *

image


No doubts that async/await pattern has significantly simplified working with asynchronous operations in C#. However, this simplification relates only to the situation when asynchronous operations are executed consequently. If we need to execute several asynchronous operations simultaneously (e.g. we need to call several micro-services) then we do not have many built-in capabilities and most probably Task.WhenAll will be used:


Task<SomeType1> someAsyncOp1 = SomeAsyncOperation1();
Task<SomeType2> someAsyncOp2 = SomeAsyncOperation2();
Task<SomeType3> someAsyncOp3 = SomeAsyncOperation3();
Task<SomeType4> someAsyncOp4 = SomeAsyncOperation4();
await Task.WhenAll(someAsyncOp1, someAsyncOp2, someAsyncOp4);
var result = new SomeContainer(
     someAsyncOp1.Result,someAsyncOp2.Result,someAsyncOp3.Result, someAsyncOp4.Result);

This is a working solution, but it is quite verbose and not very reliable (you can forget to add a new task to “WhenAll”). I would prefer something like that instead:


var result =  await 
    from r1 in SomeAsyncOperation1()
    from r2 in SomeAsyncOperation2()
    from r3 in SomeAsyncOperation3()
    from r4 in SomeAsyncOperation4()
    select new SomeContainer(r1, r2, r3, r4);

Further I will tell you what is necessary for this construction to work...

Read more →
Total votes 13: ↑12 and ↓1 +11
Views 17K
Comments 4

“Maybe” monad through async/await in C# (No Tasks!)

.NET *C# *Functional Programming *


Generalized async return types — it is a new C#7 feature that allows using not only Task as a return type of async methods but also other types (classes or structures) that satisfy some specific requirements.


At the same time, async/await is a way to call a set of "continuation" functions inside some context which is an essence of another design pattern — Monad. So, can we use async/await to write a code which will behave in the same way like if we used monads? It turns out that — yes (with some reservations). For example, the code below is compilable and working:


async Task Main()
{
  foreach (var s in new[] { "1,2", "3,7,1", null, "1" })
  {
      var res = await Sum(s).GetMaybeResult();
      Console.WriteLine(res.IsNothing ? "Nothing" : res.GetValue().ToString());
  }
  // 3, 11, Nothing, Nothing
}

async Maybe<int> Sum(string input)
{
    var args = await Split(input);//No result checking
    var result = 0;
    foreach (var arg in args)
        result += await Parse(arg);//No result checking
    return result;
}

Maybe<string[]> Split(string str)
{
  var parts = str?.Split(',').Where(s=>!string.IsNullOrWhiteSpace(s)).ToArray();
  return parts == null || parts.Length < 2 ? Maybe<string[]>.Nothing() : parts;
}

Maybe<int> Parse(string str)
    => int.TryParse(str, out var result) ? result : Maybe<int>.Nothing();

Further, I will explain how the code works...

Read more →
Total votes 12: ↑10 and ↓2 +8
Views 17K
Comments 1

«Reader» monad through async/await in C#

.NET *C# *Functional Programming *

In my previous article I described how to achieve the "Maybe" monad behavior using async/await operators. This time I am going to show how to implement another popular design pattern "Reader Monad" using the same techniques.


That pattern allows implicit passing some context into some function without using function parameters or shared global objects and it can be considered as yet another way to implement dependency injection. For example:


class Config { public string Template; }

public static async Task Main()
{
    Console.WriteLine(await GreetGuys().Apply(new Config {Template = "Hi, {0}!"}));
    //(Hi, John!, Hi, Jose!)

    Console.WriteLine(await GreetGuys().Apply(new Config {Template = "¡Hola, {0}!" }));
    //(¡Hola, John!, ¡Hola, Jose!)
}

//These functions do not have any link to any instance of the Config class.
public static async Reader<(string gJohn, string gJose)> GreetGuys() 
    => (await Greet("John"), await Greet("Jose"));

static async Reader<string> Greet(string name) 
    => string.Format(await ExtractTemplate(), name);

static async Reader<string> ExtractTemplate() 
    => await Reader<string>.Read<Config>(c => c.Template);
Read more →
Total votes 11: ↑11 and ↓0 +11
Views 5.5K
Comments 2

Монада «Maybe» через async/await в C# (без Task-oв!)

.NET *C# *Functional Programming *
Translation


Обобщенные асинхронные типы возвращаемых значений — это новая возможность появившаяся в C# 7, которая позволяет использовать не только Task в качестве возвращаемого типа асинхронных (async/await) методов, но также и любые другие типы (классы или структуры), удовлетворяющие определенным требованиям.


В то же время async/await — это способ последовательно вызвать некий набор функций внутри некоторого контекста, что является сущностью шаблона проектирования Монада. Возникает вопрос, можем ли мы использовать async/await для написания кода, который будет вести себя так же, как если бы мы использовали монады? Оказывается, что да (с некоторыми оговорками). Например, приведенный ниже код компилируется и работает:


async Task Main()
{
  foreach (var s in new[] { "1,2", "3,7,1", null, "1" })
  {
      var res = await Sum(s).GetMaybeResult();
      Console.WriteLine(res.IsNothing ? "Nothing" : res.GetValue().ToString());
  }
  // 3, 11, Nothing, Nothing
}

async Maybe<int> Sum(string input)
{
    var args = await Split(input);//Нет проверки результата
    var result = 0;
    foreach (var arg in args)
        result += await Parse(arg);//Нет проверки результата
    return result;
}

Maybe<string[]> Split(string str)
{
  var parts = str?.Split(',').Where(s=>!string.IsNullOrWhiteSpace(s)).ToArray();
  return parts == null || parts.Length < 2 ? Maybe<string[]>.Nothing() : parts;
}

Maybe<int> Parse(string str)
    => int.TryParse(str, out var result) ? result : Maybe<int>.Nothing();

Далее я объясняю, как работает этот код ...

Читать дальше →
Total votes 21: ↑20 and ↓1 +19
Views 11K
Comments 29

Монада «Reader» через async/await в C#

.NET *C# *Functional Programming *
Translation


В моей предыдущей статье я описал, как реализовать паттерн "Монада Maybe" с помощью операторов async / await. В этот раз я расскажу, как реализовать другой популярный шаблон проектирования "Монада Reader", используя те же приемы.


Этот шаблон позволяет неявно передать некий контекст в иерархию вызовов функции без использования параметров или полей классов, и его можно рассматривать как еще один способ реализации внедрения зависимости (Dependency Injection). Например:

Читать дальше →
Total votes 9: ↑9 and ↓0 +9
Views 6.3K
Comments 9