Beispiel #1
0
        public static Opt <int> BinarySearch <element>(this IReadOnlyList <element> list, element value, IComparer <element> comparer = null, Ord fallback = default(Ord))
        {
            if (list == null)
            {
                throw new ArgumentNullException(nameof(list));
            }

            int lo = 0;
            int hi = list.Count - 1;

            comparer = comparer ?? Comparer <element> .Default;

            while (lo <= hi)
            {
                int i = lo + ((hi - lo) >> 1);

                int c = comparer.Compare(list[i], value);
                if (c == 0)
                {
                    return(i);
                }
                if (c < 0)
                {
                    lo = i + 1;
                }
                else
                {
                    hi = i - 1;
                }
            }

            var fallenBack = fallback.Case(lo - 1, -1, lo);

            return(fallenBack.IsOnSemiInterval(0, list.Count, AInt32.Class).ThenOrDefault(fallenBack.PureOpt()));
        }
Beispiel #2
0
 /// <summary>
 /// `Greater than` projection test
 /// </summary>
 public static bool IsGt(this Ord that) => that.Case(false, false, true);
Beispiel #3
0
 /// <summary>
 /// `Less than` projection test
 /// </summary>
 public static bool IsLt(this Ord that) => that.Case(true, false, false);
Beispiel #4
0
 /// <summary>
 /// `Greater than` projection
 /// </summary>
 public static Unit Gt(this Ord that) =>
 that.Case(Failing <Unit> .Tag(that, nameof(Lt)), Failing <Unit> .Tag(that, nameof(Lt)), Id);
Beispiel #5
0
 /// <summary>
 /// `Less than` projection
 /// </summary>
 public static Unit Lt(this Ord that) =>
 that.Case(Id, Failing <Unit> .Tag(that, nameof(Lt)), Failing <Unit> .Tag(that, nameof(Lt)));
Beispiel #6
0
 /// <summary>
 /// Basic pattern matcher (lazy)
 /// </summary>
 public static res Case <res>(this Ord that, Func <Unit, res> Lt, Func <Unit, res> Eq, Func <Unit, res> Gt) =>
 that.Case <Func <Unit, res> >(Lt, Eq, Gt).ToValue();
Beispiel #7
0
 /// <summary>
 /// Basic pattern matcher
 /// </summary>
 public static res Case <res>(this Ord that, res Lt, res Eq, res Gt) =>
 that.Case(Lt, Fst, Eq, Fst, Gt, Fst);
Beispiel #8
0
 /// <summary>
 /// From well-order to neg/zero/pos integer
 /// </summary>
 public static int ToInt(this Ord that) => that.Case(-1, 0, 1);