static FingerTree <Node <Node <T, M>, M>, M> AddDigits2 <T, M>(Measured <Node <T, M>, M> m, FingerTree <Node <Node <T, M>, M>, M> m1, Digit <Node <T, M>, M> x, Node <T, M> n1, Node <T, M> n2, Digit <Node <T, M>, M> y, FingerTree <Node <Node <T, M>, M>, M> m2) { var mk = new MakeTree <Node <T, M>, M>(m); return(x.Match(x1 => y.Match(y1 => Append2(m, m1, mk.Node2(x1.V, n1), mk.Node2(n2, y1.V), m2), y2 => Append2(m, m1, mk.Node3(x1.V, n1, n2), mk.Node2(y2.V1, y2.V2), m2), y3 => Append2(m, m1, mk.Node3(x1.V, n1, n2), mk.Node3(y3.V1, y3.V2, y3.V3), m2), y4 => Append3(m, m1, mk.Node3(x1.V, n1, n2), mk.Node2(y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)), x2 => y.Match(y1 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node2(n2, y1.V), m2), y2 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node3(n2, y2.V1, y2.V2), m2), y3 => Append3(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node2(n2, y3.V1), mk.Node2(y3.V2, y3.V3), m2), y4 => Append3(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node3(n2, y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)), x3 => y.Match(y1 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y1.V), m2), y2 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(n1, n2), mk.Node2(y2.V1, y2.V2), m2), y3 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y3.V1), mk.Node2(y3.V2, y3.V3), m2), y4 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y4.V1), mk.Node3(y4.V2, y4.V3, y4.V4), m2)), x4 => y.Match(y1 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, n1), mk.Node2(n2, y1.V), m2), y2 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2), mk.Node2(y2.V1, y2.V2), m2), y3 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2), mk.Node3(y3.V1, y3.V2, y3.V3), m2), y4 => Append4(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2), mk.Node2(y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)))); }
static FingerTree <Node <T, M>, M> AddDigits0 <T, M>(Measured <T, M> m, FingerTree <Node <T, M>, M> m1, Digit <T, M> s1, Digit <T, M> p2, FingerTree <Node <T, M>, M> m2) { var mk = new MakeTree <T, M>(m); return(s1.Match(x1 => p2.Match(y1 => Append1(m, m1, mk.Node2(x1.V, y1.V), m2), y2 => Append1(m, m1, mk.Node3(x1.V, y2.V1, y2.V2), m2), y3 => Append2(m, m1, mk.Node2(x1.V, y3.V1), mk.Node2(y3.V2, y3.V3), m2), y4 => Append2(m, m1, mk.Node3(x1.V, y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)), x2 => p2.Match(y1 => Append1(m, m1, mk.Node3(x2.V1, x2.V2, y1.V), m2), y2 => Append2(m, m1, mk.Node2(x2.V1, x2.V2), mk.Node2(y2.V1, y2.V2), m2), y3 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, y3.V1), mk.Node2(y3.V2, y3.V3), m2), y4 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, y4.V1), mk.Node3(y4.V2, y4.V3, y4.V4), m2)), x3 => p2.Match(y1 => Append2(m, m1, mk.Node2(x3.V1, x3.V2), mk.Node2(x3.V3, y1.V), m2), y2 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(y2.V1, y2.V2), m2), y3 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(y3.V1, y3.V2, y3.V3), m2), y4 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)), x4 => p2.Match(y1 => Append2(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, y1.V), m2), y2 => Append2(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, y2.V1, y2.V2), m2), y3 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, y3.V1), mk.Node2(y3.V2, y3.V3), m2), y4 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)))); }
public override FingerTree <T, M> Concat(FingerTree <T, M> t) { Measured <T, M> m = Measured; return(t.Match(e => this, s => AddRight(s.Item), d => new Deep <T, M>(m, m.Append(Size, d.Size), _prefix, AddDigits0(m, _middle, _suffix, d._prefix, d._middle), d._suffix))); }
public Deep(Measured <T, M> measured, M size, Digit <T, M> prefix, FingerTree <Node <T, M>, M> middle, Digit <T, M> suffix) : base(measured, size) { _mk = new MakeTree <T, M>(measured); _prefix = prefix; _middle = middle; _suffix = suffix; }
static FingerTree <Node <T, M>, M> Append1 <T, M>(Measured <T, M> m, FingerTree <Node <T, M>, M> t1, Node <T, M> n1, FingerTree <Node <T, M>, M> t2) { return(t1.Match(e => t2.AddLeft(n1), s => t2.AddLeft(n1).AddLeft(s.Item), d => t2.Match(e2 => t1.AddRight(n1), s2 => t1.AddRight(n1).AddRight(s2.Item), d2 => new Deep <Node <T, M>, M>(m.Node, m.Append(m.Append(d.Size, m.Node.Measure(n1)), d2.Size), d._prefix, AddDigits1(m.Node, d._middle, d._suffix, n1, d2._prefix, d2._middle), d2._suffix)))); }
static FingerTree <Node <T, M>, M> Append4 <T, M>(Measured <T, M> m, FingerTree <Node <T, M>, M> t1, Node <T, M> n1, Node <T, M> n2, Node <T, M> n3, Node <T, M> n4, FingerTree <Node <T, M>, M> t2) { return(t1.Match(e => t2.AddLeft(n4).AddLeft(n3).AddLeft(n2).AddLeft(n1), s => t2.AddLeft(n4).AddLeft(n3).AddLeft(n2).AddLeft(n1).AddLeft(s.Item), d => t2.Match(e2 => t2.AddRight(n1).AddRight(n2).AddRight(n3).AddRight(n4), s2 => t2.AddRight(n1).AddRight(n2).AddRight(n3).AddRight(n4).AddRight(s2.Item), d2 => new Deep <Node <T, M>, M>(m.Node, m.Append( m.Append( m.Append( m.Append( m.Append(d.Size, n1.Measure), n2.Measure), n3.Measure), n4.Measure), d2.Size), d._prefix, AddDigits4(m.Node, d._middle, d._suffix, n1, n2, n3, n4, d2._prefix, d2._middle), d2._suffix)))); }
public abstract FingerTree <T, M> Concat(FingerTree <T, M> t);
public override FingerTree <T, M> Concat(FingerTree <T, M> t) { return(t.AddLeft(_item)); }
public override Split <T, FingerTree <T, M>, M> Split(MeasurePredicate <M> predicate, M acc) { var mk = new MakeTree <Node <T, M>, M>(Measured.Node); M prefixSize = Measured.Append(acc, _prefix.Size); if (predicate(prefixSize)) { Split <T, Digit <T, M>, M> split = _prefix.Split(predicate, acc); FingerTree <T, M> leftTree = split.Left == null?_mk.Empty() : split.Left.ToTree(); FingerTree <T, M> rightTree; if (split.Right != null) { rightTree = _mk.Deep(split.Right, _middle, _suffix); } else { rightTree = _middle.Match(e => _suffix.ToTree(), s => _mk.Deep(s.Item.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3)), mk.Empty(), _suffix), d => { var leftView = _middle.Left; return(_mk.Deep(leftView.Head.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3)), leftView.Tail, _suffix)); }); } return(new Split <T, FingerTree <T, M>, M>(leftTree, split.Item, rightTree)); } M middleSize = Measured.Append(prefixSize, _middle.Size); if (predicate(middleSize)) { Split <Node <T, M>, FingerTree <Node <T, M>, M>, M> split = _middle.Split(predicate, prefixSize); Split <T, Digit <T, M>, M> splitMidLeft = split.Item .Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3)) .Split(predicate, Measured.Append(prefixSize, split.Left.Size)); FingerTree <T, M> leftTree = _mk.Deep(_prefix, split.Left, splitMidLeft.Left); FingerTree <T, M> rightTree = _mk.Deep(splitMidLeft.Right, split.Right, _suffix); return(new Split <T, FingerTree <T, M>, M>(leftTree, splitMidLeft.Item, rightTree)); } Split <T, Digit <T, M>, M> splitSuffix = _suffix.Split(predicate, middleSize); FingerTree <T, M> right = splitSuffix.Right == null?_mk.Empty() : splitSuffix.Right.ToTree(); FingerTree <T, M> left; if (splitSuffix.Left != null) { left = _mk.Deep(_prefix, _middle, splitSuffix.Left); } else { left = _middle.Match(e => _prefix.ToTree(), s => _mk.Deep(_prefix, mk.Empty(), s.Item.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3))), d => { var rightView = _middle.Right; return(_mk.Deep(_prefix, rightView.Tail, rightView.Head.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3)))); }); } return(new Split <T, FingerTree <T, M>, M>(left, splitSuffix.Item, right)); }
public override FingerTree <T, M> Concat(FingerTree <T, M> t) { return(t); }