-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathEffectFnSeq.cs
100 lines (72 loc) · 2.92 KB
/
EffectFnSeq.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) TotalSoft.
// This source code is licensed under the MIT license.
using System;
namespace NBB.Core.Effects
{
public abstract class EffectFnSeq<TA, TB>
{
public EffectFnSeq<TA, TC> Append<TC>(Func<TB, Effect<TC>> continuation)
=> new EffectFnSeq<TA, TC>.Node<TB>(this, new EffectFnSeq<TB, TC>.Leaf(continuation));
public EffectFnSeq<TA, TC> AppendMany<TC>(EffectFnSeq<TB, TC> continuations)
=> new EffectFnSeq<TA, TC>.Node<TB>(this, continuations);
public abstract LeftEffectFnSeq<TA, TB> ToLeft();
internal abstract LeftEffectFnSeq<TA, TC> Go<TC>(EffectFnSeq<TB, TC> continuations);
public Effect<TB> Apply(TA a)
=> ToLeft().Apply(a);
public abstract int GetCount();
internal class Leaf : EffectFnSeq<TA, TB>
{
public Func<TA, Effect<TB>> Single { get; }
public Leaf(Func<TA, Effect<TB>> single)
{
Single = single;
}
public override LeftEffectFnSeq<TA, TB> ToLeft()
=> new LeftEffectFnSeq<TA, TB>.Singleton(Single);
internal override LeftEffectFnSeq<TA, TC> Go<TC>(EffectFnSeq<TB, TC> continuations)
=> new LeftEffectFnSeq<TA, TC>.Cons<TB>(Single, continuations);
public override int GetCount() => 1;
}
internal class Node<TX> : EffectFnSeq<TA, TB>
{
public EffectFnSeq<TA, TX> Left { get; }
public EffectFnSeq<TX, TB> Right { get; }
public Node(EffectFnSeq<TA, TX> left, EffectFnSeq<TX, TB> right)
{
Left = left;
Right = right;
}
public override LeftEffectFnSeq<TA, TB> ToLeft()
=> Left.Go(Right);
public override int GetCount() => Left.GetCount() + Right.GetCount();
internal override LeftEffectFnSeq<TA, TC> Go<TC>(EffectFnSeq<TB, TC> continuations)
=> Left.Go(new EffectFnSeq<TX, TC>.Node<TB>(Right, continuations));
}
}
public abstract class LeftEffectFnSeq<TA, TB>
{
public abstract Effect<TB> Apply(TA a);
internal class Singleton : LeftEffectFnSeq<TA, TB>
{
public Func<TA, Effect<TB>> Single { get; }
public Singleton(Func<TA, Effect<TB>> single)
{
Single = single;
}
public override Effect<TB> Apply(TA a)
=> Single(a);
}
internal class Cons<TX> : LeftEffectFnSeq<TA, TB>
{
public Func<TA, Effect<TX>> Head { get; }
public EffectFnSeq<TX, TB> Tail { get; }
public Cons(Func<TA, Effect<TX>> head, EffectFnSeq<TX, TB> tail)
{
Head = head;
Tail = tail;
}
public override Effect<TB> Apply(TA a)
=> Head(a).Bind2(Tail);
}
}
}