<commit_before>﻿using MorleyDev.Reactive.Monad;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Reactive.Threading.Tasks;

namespace System.Linq
{
	public static class Monadic
	{
        public static LazyValue<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, T> functor)
            where TDisposable : IDisposable => Defer(() =>
            {
                using (var disposable = factory())
                    return functor(disposable);
            });

        public static Maybe<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Maybe<T>> functor)
            where TDisposable : IDisposable => Defer(() =>
            {
                using (var disposable = factory())
                    return functor(disposable);
            });

        public static LazyValue<T> Return<T>(T value) => LazyValue.Return(value);
		public static LazyValue<T> Defer<T>(Func<T> value) => LazyValue.Defer(value);
		public static Maybe<T> Defer<T>(Func<Maybe<T>> value) => Maybe.Defer(value);

		public static Maybe<U> Select<U, T>(this Maybe<T> self, Func<T, U> mapper) => Maybe<U>.From(self.AsEnumerable().Select(mapper));
		public static Maybe<T> Where<T>(this Maybe<T> self, Func<T, bool> predicate) => Maybe<T>.From(self.AsEnumerable().Where(predicate));
		public static Maybe<U> SelectMany<U, T>(this Maybe<T> self, Func<T, LazyValue<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static Maybe<U> SelectMany<U, T>(this Maybe<T> self, Func<T, Maybe<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static LazyValue<T> DefaultIfEmpty<T>(this Maybe<T> self, T defaultValue = default(T)) => LazyValue<T>.From(self.AsEnumerable().DefaultIfEmpty(defaultValue).Single);

		public static LazyValue<U> Select<U, T>(this LazyValue<T> self, Func<T, U> mapper) => LazyValue<U>.From(self.AsEnumerable().Select(mapper).Single);
		public static Maybe<T> Where<T>(this LazyValue<T> self, Func<T, bool> predicate) => Maybe<T>.From(self.AsEnumerable().Where(predicate));
		public static LazyValue<U> SelectMany<U, T>(this LazyValue<T> self, Func<T, LazyValue<U>> mapper) => LazyValue<U>.From(self.AsEnumerable().SelectMany(mapper).Single);
		public static Maybe<U> SelectMany<U, T>(this LazyValue<T> self, Func<T, Maybe<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static LazyValue<U> DefaultIfEmpty<U, T>(this LazyValue<T> self, Func<T, Maybe<U>> mapper) => LazyValue<U>.From(self.AsEnumerable().SelectMany(mapper).Single);

		public static LazyValue<T> SingleLazy<T>(this IEnumerable<T> self) => LazyValue<T>.From(self.Single);
		public static Maybe<T> FirstOrNone<T>(this IEnumerable<T> self) => Maybe<T>.From(self.Take(1));

		public static LazyValue<TSource> AggregateLazy<TSource>(this IEnumerable<TSource> self, Func<TSource, TSource, TSource> reducer)
			=> Defer(() => self.Aggregate(reducer));
		public static LazyValue<TAccumulate> AggregateLazy<TSource, TAccumulate>(this IEnumerable<TSource> self, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> reducer)
			=> Defer(() => self.Aggregate(seed, reducer));
	}
}

namespace System.Reactive.Linq
{
	public static class MonadicAsync
	{
		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, T> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => Observable.Return(method(disposable))));
			
		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, IO<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable)));

		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Task<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable).ToObservable()));

		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Maybe<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => Observable.Return(method(disposable))));
			
		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, MaybeIO<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.MaybeIO.From(Observable.Using(factory, disposable => method(disposable)));

		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Task<Maybe<T>>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable).ToObservable()));

		public static IObservable<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, IObservable<T>> method)
			where TDisposable : IDisposable
			=> (Observable.Using(factory, disposable => method(disposable)));

		public static IO<T> Return<T>(T value) => MorleyDev.Reactive.Monad.IO.Return(value);
		public static MaybeIO<T> Return<T>(Maybe<T> value) => MorleyDev.Reactive.Monad.IO.Return(value);
		public static IO<T> Run<T>(Func<T> value) => MorleyDev.Reactive.Monad.IO.Run(value);
		public static IO<T> Defer<T>(Func<Task<T>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);
		public static MaybeIO<T> Run<T>(Func<Maybe<T>> value) => MorleyDev.Reactive.Monad.IO.Run(value);
		public static MaybeIO<T> Defer<T>(Func<Task<Maybe<T>>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);
		public static MaybeIO<T> Defer<T>(Func<IO<Maybe<T>>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);<commit_msg>Added void->unit Run and Defer to Monadic<commit_after>﻿using MorleyDev.Reactive.Monad;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Reactive.Threading.Tasks;

namespace System.Linq
{
	public static class Monadic
	{
        public static LazyValue<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, T> functor)
            where TDisposable : IDisposable => Defer(() =>
            {
                using (var disposable = factory())
                    return functor(disposable);
            });

        public static Maybe<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Maybe<T>> functor)
            where TDisposable : IDisposable => Defer(() =>
            {
                using (var disposable = factory())
                    return functor(disposable);
            });

        public static LazyValue<T> Return<T>(T value) => LazyValue.Return(value);
		public static LazyValue<T> Defer<T>(Func<T> value) => LazyValue.Defer(value);
		public static LazyValue<System.Reactive.Unit> Defer<T>(Action value) => LazyValue.Defer(() => { value(); return System.Reactive.Unit.Default; });
		public static Maybe<T> Defer<T>(Func<Maybe<T>> value) => Maybe.Defer(value);

		public static Maybe<U> Select<U, T>(this Maybe<T> self, Func<T, U> mapper) => Maybe<U>.From(self.AsEnumerable().Select(mapper));
		public static Maybe<T> Where<T>(this Maybe<T> self, Func<T, bool> predicate) => Maybe<T>.From(self.AsEnumerable().Where(predicate));
		public static Maybe<U> SelectMany<U, T>(this Maybe<T> self, Func<T, LazyValue<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static Maybe<U> SelectMany<U, T>(this Maybe<T> self, Func<T, Maybe<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static LazyValue<T> DefaultIfEmpty<T>(this Maybe<T> self, T defaultValue = default(T)) => LazyValue<T>.From(self.AsEnumerable().DefaultIfEmpty(defaultValue).Single);

		public static LazyValue<U> Select<U, T>(this LazyValue<T> self, Func<T, U> mapper) => LazyValue<U>.From(self.AsEnumerable().Select(mapper).Single);
		public static Maybe<T> Where<T>(this LazyValue<T> self, Func<T, bool> predicate) => Maybe<T>.From(self.AsEnumerable().Where(predicate));
		public static LazyValue<U> SelectMany<U, T>(this LazyValue<T> self, Func<T, LazyValue<U>> mapper) => LazyValue<U>.From(self.AsEnumerable().SelectMany(mapper).Single);
		public static Maybe<U> SelectMany<U, T>(this LazyValue<T> self, Func<T, Maybe<U>> mapper) => Maybe<U>.From(self.AsEnumerable().SelectMany(mapper));
		public static LazyValue<U> DefaultIfEmpty<U, T>(this LazyValue<T> self, Func<T, Maybe<U>> mapper) => LazyValue<U>.From(self.AsEnumerable().SelectMany(mapper).Single);

		public static LazyValue<T> SingleLazy<T>(this IEnumerable<T> self) => LazyValue<T>.From(self.Single);
		public static Maybe<T> FirstOrNone<T>(this IEnumerable<T> self) => Maybe<T>.From(self.Take(1));

		public static LazyValue<TSource> AggregateLazy<TSource>(this IEnumerable<TSource> self, Func<TSource, TSource, TSource> reducer)
			=> Defer(() => self.Aggregate(reducer));
		public static LazyValue<TAccumulate> AggregateLazy<TSource, TAccumulate>(this IEnumerable<TSource> self, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> reducer)
			=> Defer(() => self.Aggregate(seed, reducer));
	}
}

namespace System.Reactive.Linq
{
	public static class MonadicAsync
	{
		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, T> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => Observable.Return(method(disposable))));
			
		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, IO<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable)));

		public static IO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Task<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable).ToObservable()));

		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Maybe<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => Observable.Return(method(disposable))));
			
		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, MaybeIO<T>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.MaybeIO.From(Observable.Using(factory, disposable => method(disposable)));

		public static MaybeIO<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, Task<Maybe<T>>> method)
			where TDisposable : IDisposable
			=> MorleyDev.Reactive.Monad.IO.From(Observable.Using(factory, disposable => method(disposable).ToObservable()));

		public static IObservable<T> Using<T, TDisposable>(Func<TDisposable> factory, Func<TDisposable, IObservable<T>> method)
			where TDisposable : IDisposable
			=> (Observable.Using(factory, disposable => method(disposable)));

		public static IO<T> Return<T>(T value) => MorleyDev.Reactive.Monad.IO.Return(value);
		public static MaybeIO<T> Return<T>(Maybe<T> value) => MorleyDev.Reactive.Monad.IO.Return(value);
		public static IO<T> Run<T>(Func<T> value) => MorleyDev.Reactive.Monad.IO.Run(value);
		public static IO<Unit> Run(Action value) => MorleyDev.Reactive.Monad.IO.Run(value);
		public static IO<T> Defer<T>(Func<Task<T>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);
		public static IO<Unit> Defer(Func<Task> value) => MorleyDev.Reactive.Monad.IO.Defer(async () => { await value(); return Unit.Default; });
		public static MaybeIO<T> Run<T>(Func<Maybe<T>> value) => MorleyDev.Reactive.Monad.IO.Run(value);
		public static MaybeIO<T> Defer<T>(Func<Task<Maybe<T>>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);
		public static MaybeIO<T> Defer<T>(Func<IO<Maybe<T>>> value) => MorleyDev.Reactive.Monad.IO.Defer(value);
{'fraction_non_alphanumeric': 0.153068105192178, 'fraction_numerical': 0.00016857720836142953, 'mean_word_length': 5.673228346456693, 'pattern_counts': {'":': 0, '<': 306, '<?xml version=': 0, '>': 400, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1207442', 'n_tokens_mistral': 4237, 'n_tokens_neox': 3936, 'n_words': 774}