Skip to content

Commit

Permalink
Put all of maybe effect example in one file (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
atifaziz authored Jul 25, 2024
1 parent 70df1d3 commit 473c941
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 128 deletions.
17 changes: 0 additions & 17 deletions samples/Eff.Examples.Maybe/Maybe.cs

This file was deleted.

14 changes: 0 additions & 14 deletions samples/Eff.Examples.Maybe/MaybeEffect.cs

This file was deleted.

79 changes: 0 additions & 79 deletions samples/Eff.Examples.Maybe/MaybeEffectHandler.cs

This file was deleted.

118 changes: 100 additions & 18 deletions samples/Eff.Examples.Maybe/Program.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,115 @@
using System;
using System.Threading.Tasks;
using Nessos.Effects;
using Nessos.Effects.Handlers;

namespace Nessos.Effects.Examples.Maybe
static async Eff<int> Divide(int m, int n)
{
class Program
return (n == 0) ? await MaybeEffect.Nothing<int>() : await MaybeEffect.Just(m / n);
}

static async Eff DivideAndReportToConsole(int m, int n)
{
Console.Write($"Calculating {m} / {n}: ");
var result = await Divide(m, n);
Console.WriteLine($"Got {result}!");
}

static async Eff Test()
{
for (var i = 0; i < 100; i++)
{
static async Eff<int> Divide(int m, int n)
{
return (n == 0) ? await MaybeEffect.Nothing<int>() : await MaybeEffect.Just<int>(m / n);
}
await DivideAndReportToConsole(23, 5 - i);
}
}

await MaybeEffectHandler.Run(Test());

public readonly struct Maybe<T>
{
public bool HasValue { get; }
public T Value { get; }

private Maybe(T value) => (HasValue, Value) = (true, value);

public static Maybe<T> Nothing { get; } = new();
public static Maybe<T> Just(T value) => new(value);
}

public class MaybeEffect<T> : Effect<T>
{
public Maybe<T> Result { get; init; }
}

public static class MaybeEffect
{
public static MaybeEffect<T> Nothing<T>() => new() { Result = Maybe<T>.Nothing };
public static MaybeEffect<T> Just<T>(T t) => new() { Result = Maybe<T>.Just(t) };
}

public static class MaybeEffectHandler
{
public static async Task<Maybe<TResult>> Run<TResult>(Eff<TResult> eff)
{
var stateMachine = eff.GetStateMachine();
var handler = new MaybeEffectHandler<TResult>();
await handler.Handle(stateMachine);

return stateMachine.IsCompleted ?
Maybe<TResult>.Just(stateMachine.GetResult()) :
Maybe<TResult>.Nothing;
}

public static Task<Maybe<Unit>> Run(Eff eff)
{
return Run(Helper());

static async Eff DivideAndReportToConsole(int m, int n)
async Eff<Unit> Helper() { await eff; return Unit.Value; }
}
}

public class MaybeEffectHandler<TResult> : IEffectHandler
{
private bool _breakExecution;

public ValueTask Handle<TValue>(EffectAwaiter<TValue> awaiter)
{
switch (awaiter.Effect)
{
Console.Write($"Calculating {m} / {n}: ");
var result = await Divide(m, n);
Console.WriteLine($"Got {result}!");
case MaybeEffect<TValue> { Result: { HasValue: true, Value: var value } }:
awaiter.SetResult(value);
break;

case MaybeEffect<TValue>:
_breakExecution = true;
break;
}

static async Eff Test()
return default;
}

public async ValueTask Handle<TValue>(EffStateMachine<TValue> stateMachine)
{
while (!_breakExecution)
{
for (int i = 0; i < 100; i++)
stateMachine.MoveNext();

switch (stateMachine)
{
await DivideAndReportToConsole(23, 5 - i);
}
}
case { Position: StateMachinePosition.Result or StateMachinePosition.Exception }:
return;

static async Task Main()
{
await MaybeEffectHandler.Run(Test());
case { Position: StateMachinePosition.TaskAwaiter, TaskAwaiter: { } awaiter }:
await awaiter;
break;

case { Position: StateMachinePosition.EffAwaiter, EffAwaiter: { } awaiter }:
await awaiter.Accept(this);
break;

default:
throw new Exception($"Invalid state machine position {stateMachine.Position}.");
}
}
}
}

0 comments on commit 473c941

Please sign in to comment.